summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/profiler
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/profiler')
-rw-r--r--js/src/jit-test/tests/profiler/AutoEntryMonitor-01.js50
-rw-r--r--js/src/jit-test/tests/profiler/AutoEntryMonitor-02.js12
-rw-r--r--js/src/jit-test/tests/profiler/bug1135703.js6
-rw-r--r--js/src/jit-test/tests/profiler/bug1161351.js16
-rw-r--r--js/src/jit-test/tests/profiler/bug1164448.js26
-rw-r--r--js/src/jit-test/tests/profiler/bug1211962.js11
-rw-r--r--js/src/jit-test/tests/profiler/bug1231925.js6
-rw-r--r--js/src/jit-test/tests/profiler/bug1233921.js19
-rw-r--r--js/src/jit-test/tests/profiler/bug1242840.js15
-rw-r--r--js/src/jit-test/tests/profiler/bug1261324.js24
-rw-r--r--js/src/jit-test/tests/profiler/bug1352507-1.js3
-rw-r--r--js/src/jit-test/tests/profiler/bug1427774.js29
-rw-r--r--js/src/jit-test/tests/profiler/bug1478509.js5
-rw-r--r--js/src/jit-test/tests/profiler/bug1502744.js20
-rw-r--r--js/src/jit-test/tests/profiler/bug1563889.js3
-rw-r--r--js/src/jit-test/tests/profiler/bug1774149.js14
-rw-r--r--js/src/jit-test/tests/profiler/bug1782003.js28
-rw-r--r--js/src/jit-test/tests/profiler/bug925309.js2
-rw-r--r--js/src/jit-test/tests/profiler/debugmode-osr-exception-return-addr.js16
-rw-r--r--js/src/jit-test/tests/profiler/debugmode-osr-resume-addr.js11
-rw-r--r--js/src/jit-test/tests/profiler/enterjit-osr-disabling-earlyret.js13
-rw-r--r--js/src/jit-test/tests/profiler/enterjit-osr-disabling.js9
-rw-r--r--js/src/jit-test/tests/profiler/enterjit-osr-enabling-earlyret.js12
-rw-r--r--js/src/jit-test/tests/profiler/enterjit-osr-enabling.js8
-rw-r--r--js/src/jit-test/tests/profiler/enterjit-osr.js8
-rw-r--r--js/src/jit-test/tests/profiler/exception-unwind-hook.js22
-rw-r--r--js/src/jit-test/tests/profiler/getter-setter-ic.js32
-rw-r--r--js/src/jit-test/tests/profiler/interpreter-stacks.js105
-rw-r--r--js/src/jit-test/tests/profiler/ion-rectifier-frame-bug1530351.js6
-rw-r--r--js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-1.js10
-rw-r--r--js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-2.js9
-rw-r--r--js/src/jit-test/tests/profiler/pc-count-profiler.js53
-rw-r--r--js/src/jit-test/tests/profiler/test-baseline-eval-frame-profiling.js11
-rw-r--r--js/src/jit-test/tests/profiler/test-bug1026485.js15
34 files changed, 629 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/profiler/AutoEntryMonitor-01.js b/js/src/jit-test/tests/profiler/AutoEntryMonitor-01.js
new file mode 100644
index 0000000000..c64a121b66
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/AutoEntryMonitor-01.js
@@ -0,0 +1,50 @@
+// AutoEntryMonitor should catch all entry points into JavaScript.
+
+load(libdir + 'array-compare.js');
+
+function cold_and_warm(f, params, expected) {
+ print(JSON.stringify(params));
+ print(JSON.stringify(entryPoints(params)));
+ assertEq(arraysEqual(entryPoints(params), expected), true);
+
+ // Warm up the function a bit, so the JITs will compile it, and try again.
+ if (f)
+ for (i = 0; i < 10; i++)
+ f();
+
+ assertEq(arraysEqual(entryPoints(params), expected), true);
+}
+
+function entry1() { }
+cold_and_warm(entry1, { function: entry1 }, [ "entry1" ]);
+
+var getx = { get x() { } };
+cold_and_warm(Object.getOwnPropertyDescriptor(getx, 'x').get,
+ { object: getx, property: 'x' }, [ "get x" ]);
+
+var sety = { set y(v) { } };
+cold_and_warm(Object.getOwnPropertyDescriptor(sety, 'y').set,
+ { object: sety, property: 'y', value: 'glerk' }, [ "set y" ]);
+
+cold_and_warm(Object.prototype.toString, { ToString: {} }, []);
+
+var toS = { toString: function myToString() { return "string"; } };
+cold_and_warm(toS.toString, { ToString: toS }, [ "myToString" ]);
+
+cold_and_warm(undefined, { ToNumber: 5 }, []);
+
+var vOf = { valueOf: function myValueOf() { return 42; } };
+cold_and_warm(vOf.valueOf, { ToNumber: vOf }, [ "myValueOf" ]);
+
+var toSvOf = { toString: function relations() { return Object; },
+ valueOf: function wallpaper() { return 17; } };
+cold_and_warm(() => { toSvOf.toString(); toSvOf.valueOf(); },
+ { ToString: toSvOf }, [ "relations", "wallpaper" ]);
+
+var vOftoS = { toString: function ettes() { return "6-inch lengths"; },
+ valueOf: function deathBy() { return Math; } };
+cold_and_warm(() => { vOftoS.valueOf(); vOftoS.toString(); },
+ { ToNumber: vOftoS }, [ "deathBy", "ettes" ]);
+
+
+cold_and_warm(() => 0, { eval: "Math.atan2(1,1);" }, [ "eval:entryPoint eval" ]);
diff --git a/js/src/jit-test/tests/profiler/AutoEntryMonitor-02.js b/js/src/jit-test/tests/profiler/AutoEntryMonitor-02.js
new file mode 100644
index 0000000000..1aee82068c
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/AutoEntryMonitor-02.js
@@ -0,0 +1,12 @@
+// Nested uses of AutoEntryMonitor should behave with decorum.
+
+load(libdir + 'array-compare.js');
+
+function Cobb() {
+ var twoShot = { toString: function Saito() { return Object; },
+ valueOf: function Fischer() { return "Ariadne"; } };
+ assertEq(arraysEqual(entryPoints({ ToString: twoShot }),
+ [ "Saito", "Fischer" ]), true);
+}
+
+assertEq(arraysEqual(entryPoints({ function: Cobb }), ["Cobb"]), true);
diff --git a/js/src/jit-test/tests/profiler/bug1135703.js b/js/src/jit-test/tests/profiler/bug1135703.js
new file mode 100644
index 0000000000..3bad17e943
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1135703.js
@@ -0,0 +1,6 @@
+
+for (var idx = 0; idx < 20; ++idx) {
+ newFunc("enableGeckoProfilingWithSlowAssertions(); disableGeckoProfiling();");
+}
+newFunc("enableGeckoProfiling();");
+function newFunc(x) { new Function(x)(); };
diff --git a/js/src/jit-test/tests/profiler/bug1161351.js b/js/src/jit-test/tests/profiler/bug1161351.js
new file mode 100644
index 0000000000..2da402275b
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1161351.js
@@ -0,0 +1,16 @@
+function x() { n; }
+function f() {
+ try { x(); } catch(ex) {}
+}
+var g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () {};");
+enableGeckoProfiling();
+try {
+ enableSingleStepProfiling();
+} catch (e) {
+ // Not all platforms support single-step profiling.
+}
+f();
+f();
+f();
diff --git a/js/src/jit-test/tests/profiler/bug1164448.js b/js/src/jit-test/tests/profiler/bug1164448.js
new file mode 100644
index 0000000000..23147742f1
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1164448.js
@@ -0,0 +1,26 @@
+// |jit-test| error: TypeError
+
+print = function(s) { return s.toString(); }
+var gTestcases = new Array();
+function TestCase(n, d, e, a) {
+ return gTestcases[gTc++] = this;
+}
+ dump = print;
+ for ( gTc=0; gTc < gTestcases.length; gTc++ ) {}
+function jsTestDriverEnd() {
+ for (var i = 0; i < gTestcases.length; i++)
+ gTestcases[i].dump();
+}
+TestCase();
+var g = newGlobal();
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () {};");
+enableGeckoProfiling();
+if (getBuildConfiguration()["arm-simulator"])
+ enableSingleStepProfiling(1);
+loadFile("jsTestDriverEnd();");
+loadFile("jsTestDriverEnd();");
+jsTestDriverEnd();
+function loadFile(lfVarx) {
+ try { evaluate(lfVarx); } catch (lfVare) {}
+}
diff --git a/js/src/jit-test/tests/profiler/bug1211962.js b/js/src/jit-test/tests/profiler/bug1211962.js
new file mode 100644
index 0000000000..d47d823ff2
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1211962.js
@@ -0,0 +1,11 @@
+// |jit-test| slow; skip-if: !('oomTest' in this) || helperThreadCount() === 0
+
+enableGeckoProfiling();
+var lfGlobal = newGlobal();
+for (lfLocal in this) {
+ lfGlobal[lfLocal] = this[lfLocal];
+}
+const script = 'oomTest(() => getBacktrace({args: true, locals: "123795", thisprops: true}));';
+lfGlobal.offThreadCompileToStencil(script);
+var stencil = lfGlobal.finishOffThreadStencil();
+lfGlobal.evalStencil(stencil);
diff --git a/js/src/jit-test/tests/profiler/bug1231925.js b/js/src/jit-test/tests/profiler/bug1231925.js
new file mode 100644
index 0000000000..87325b6763
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1231925.js
@@ -0,0 +1,6 @@
+// |jit-test| skip-if: !('oomTest' in this)
+
+enableGeckoProfiling();
+oomTest(function() {
+ eval("(function() {})()")
+});
diff --git a/js/src/jit-test/tests/profiler/bug1233921.js b/js/src/jit-test/tests/profiler/bug1233921.js
new file mode 100644
index 0000000000..18cce796be
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1233921.js
@@ -0,0 +1,19 @@
+g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () {}");
+enableGeckoProfiling();
+try {
+ enableSingleStepProfiling();
+} catch(e) {
+ quit();
+}
+f();
+f();
+function $ERROR() {
+ throw Error;
+}
+function f() {
+ try {
+ $ERROR()
+ } catch (ex) {}
+}
diff --git a/js/src/jit-test/tests/profiler/bug1242840.js b/js/src/jit-test/tests/profiler/bug1242840.js
new file mode 100644
index 0000000000..8770403409
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1242840.js
@@ -0,0 +1,15 @@
+// |jit-test| skip-if: !('oomTest' in this)
+
+enableGeckoProfiling();
+oomTest(() => {
+ try {
+ for (quit of ArrayBuffer);
+ } catch (e) {
+ switch (1) {
+ case 0:
+ let x
+ case 1:
+ (function() { return x; })()
+ }
+ }
+})
diff --git a/js/src/jit-test/tests/profiler/bug1261324.js b/js/src/jit-test/tests/profiler/bug1261324.js
new file mode 100644
index 0000000000..053f00928e
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1261324.js
@@ -0,0 +1,24 @@
+g = newGlobal({newCompartment: true})
+g.parent = this
+g.eval("new Debugger(parent).onExceptionUnwind = function () {}")
+enableGeckoProfiling()
+
+try {
+ // Only the ARM simulator supports single step profiling.
+ enableSingleStepProfiling();
+} catch (e) {
+ quit();
+}
+
+function assertThrowsInstanceOf(f) {
+ try {
+ f()
+ } catch (exc) {}
+}
+function testThrow(thunk) {
+ for (i = 0; i < 20; i++) {
+ iter = thunk()
+ assertThrowsInstanceOf(function() { return iter.throw(); })
+ }
+}
+testThrow(function*() {})
diff --git a/js/src/jit-test/tests/profiler/bug1352507-1.js b/js/src/jit-test/tests/profiler/bug1352507-1.js
new file mode 100644
index 0000000000..540c4d5350
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1352507-1.js
@@ -0,0 +1,3 @@
+// |jit-test| skip-if: helperThreadCount() === 0
+
+evalInWorker("enableGeckoProfiling()");
diff --git a/js/src/jit-test/tests/profiler/bug1427774.js b/js/src/jit-test/tests/profiler/bug1427774.js
new file mode 100644
index 0000000000..53a3103f3b
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1427774.js
@@ -0,0 +1,29 @@
+setJitCompilerOption("baseline.warmup.trigger", 0);
+enableGeckoProfiling();
+try {
+ enableSingleStepProfiling();
+} catch(e) {
+ quit();
+}
+function removeAdd(dbg, g) {
+ dbg.removeDebuggee(g);
+}
+function newGlobalDebuggerPair(toggleSeq) {
+ var g = newGlobal({newCompartment: true});
+ var dbg = new Debugger;
+ dbg.addDebuggee(g);
+ g.eval("" + function f() {return 100});
+ return [g, dbg];
+}
+function testTrap(toggleSeq) {
+ var [g, dbg] = newGlobalDebuggerPair(toggleSeq);
+ dbg.onEnterFrame = function(f) {
+ f.script.setBreakpoint(Symbol.iterator == (this) ^ (this), {
+ hit: function() {
+ toggleSeq(dbg, g);
+ }
+ });
+ };
+ assertEq(g.f(), 100);
+}
+testTrap(removeAdd);
diff --git a/js/src/jit-test/tests/profiler/bug1478509.js b/js/src/jit-test/tests/profiler/bug1478509.js
new file mode 100644
index 0000000000..eafe5a70b5
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1478509.js
@@ -0,0 +1,5 @@
+// |jit-test| error: SyntaxError
+enableGeckoProfiling();
+s = newGlobal();
+evalcx("let x;", s);
+evalcx("let x;", s);
diff --git a/js/src/jit-test/tests/profiler/bug1502744.js b/js/src/jit-test/tests/profiler/bug1502744.js
new file mode 100644
index 0000000000..c0f1ee3dfd
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1502744.js
@@ -0,0 +1,20 @@
+// |jit-test| error:ReferenceError
+(function(global) {
+ global.makeIterator = function makeIterator(overrides) {
+ var iterator = {
+ return: function(x) {
+ return overrides.ret(x);
+ }
+ };
+ return function() {
+ return iterator;
+ };
+ }
+})(this);
+var iterable = {};
+iterable[Symbol.iterator] = makeIterator({
+ ret: (function() {
+ enableGeckoProfilingWithSlowAssertions();
+ })
+});
+0, [...{} [throwlhs()]] = iterable;
diff --git a/js/src/jit-test/tests/profiler/bug1563889.js b/js/src/jit-test/tests/profiler/bug1563889.js
new file mode 100644
index 0000000000..c8f9776ada
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1563889.js
@@ -0,0 +1,3 @@
+// |jit-test| skip-if: !('oomTest' in this)
+for (var i = 0; i < 20; i++) {}
+oomTest(enableGeckoProfiling);
diff --git a/js/src/jit-test/tests/profiler/bug1774149.js b/js/src/jit-test/tests/profiler/bug1774149.js
new file mode 100644
index 0000000000..08c44b462b
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1774149.js
@@ -0,0 +1,14 @@
+// |jit-test| --fast-warmup
+function* f() {
+ try {
+ yield;
+ } finally {
+ for (let i = 0; i < 10; i++) {}
+ }
+}
+enableGeckoProfilingWithSlowAssertions();
+for (var i = 0; i < 25; ++i) {
+ let it = f();
+ it.next();
+ it.return();
+}
diff --git a/js/src/jit-test/tests/profiler/bug1782003.js b/js/src/jit-test/tests/profiler/bug1782003.js
new file mode 100644
index 0000000000..34219a7179
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1782003.js
@@ -0,0 +1,28 @@
+function getStack() {
+ enableGeckoProfiling();
+ let stack = readGeckoProfilingStack();
+ // The number of frames depends on JIT flags, but there must be at least
+ // one frame for the caller and at most 3 total (the global script, 'testFun'
+ // and 'getStack').
+ assertEq(stack.length > 0, true);
+ assertEq(stack.length <= 3, true);
+ assertEq(JSON.stringify(stack).includes('"testFun ('), true);
+ disableGeckoProfiling();
+}
+function testFun() {
+ // Loop until this is a JIT frame.
+ while (true) {
+ let isJitFrame = inJit();
+ if (typeof isJitFrame === "string") {
+ return; // JIT disabled.
+ }
+ if (isJitFrame) {
+ break;
+ }
+ }
+
+ // Now call getStack to check this frame is on the profiler's JIT stack.
+ getStack();
+ getStack();
+}
+testFun();
diff --git a/js/src/jit-test/tests/profiler/bug925309.js b/js/src/jit-test/tests/profiler/bug925309.js
new file mode 100644
index 0000000000..9301cb74ae
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug925309.js
@@ -0,0 +1,2 @@
+
+for(var i = 0; i < 100; enableGeckoProfiling(), i++) {}
diff --git a/js/src/jit-test/tests/profiler/debugmode-osr-exception-return-addr.js b/js/src/jit-test/tests/profiler/debugmode-osr-exception-return-addr.js
new file mode 100644
index 0000000000..f91ce610e5
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/debugmode-osr-exception-return-addr.js
@@ -0,0 +1,16 @@
+// |jit-test| error: ReferenceError
+
+var g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("new Debugger(parent).onExceptionUnwind = function () { };");
+enableGeckoProfiling();
+
+try {
+ // Only the ARM simulator supports single step profiling.
+ enableSingleStepProfiling();
+} catch (e) {
+ throw new ReferenceError;
+}
+
+enableSingleStepProfiling();
+a()
diff --git a/js/src/jit-test/tests/profiler/debugmode-osr-resume-addr.js b/js/src/jit-test/tests/profiler/debugmode-osr-resume-addr.js
new file mode 100644
index 0000000000..0246234932
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/debugmode-osr-resume-addr.js
@@ -0,0 +1,11 @@
+enableGeckoProfiling();
+try {
+ // Only the ARM simulator supports single step profiling.
+ enableSingleStepProfiling();
+} catch (e) {
+ quit(0);
+}
+var g = newGlobal({newCompartment: true});
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {};
+g.eval("var line = new Error().lineNumber; debugger;");
diff --git a/js/src/jit-test/tests/profiler/enterjit-osr-disabling-earlyret.js b/js/src/jit-test/tests/profiler/enterjit-osr-disabling-earlyret.js
new file mode 100644
index 0000000000..f8184696e8
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/enterjit-osr-disabling-earlyret.js
@@ -0,0 +1,13 @@
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+enableGeckoProfilingWithSlowAssertions();
+(function() {
+ var n = 50;
+ while (n--) {
+ disableGeckoProfiling();
+ if (!n)
+ return;
+ enableGeckoProfilingWithSlowAssertions();
+ }
+})();
diff --git a/js/src/jit-test/tests/profiler/enterjit-osr-disabling.js b/js/src/jit-test/tests/profiler/enterjit-osr-disabling.js
new file mode 100644
index 0000000000..e0663e6a95
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/enterjit-osr-disabling.js
@@ -0,0 +1,9 @@
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+enableGeckoProfilingWithSlowAssertions();
+(function() {
+ disableGeckoProfiling();
+ var n = 50;
+ while (n--);
+})();
diff --git a/js/src/jit-test/tests/profiler/enterjit-osr-enabling-earlyret.js b/js/src/jit-test/tests/profiler/enterjit-osr-enabling-earlyret.js
new file mode 100644
index 0000000000..e63531f504
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/enterjit-osr-enabling-earlyret.js
@@ -0,0 +1,12 @@
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+(function() {
+ var n = 50;
+ while (n--) {
+ enableGeckoProfilingWithSlowAssertions();
+ if (!n)
+ return;
+ disableGeckoProfiling();
+ }
+})();
diff --git a/js/src/jit-test/tests/profiler/enterjit-osr-enabling.js b/js/src/jit-test/tests/profiler/enterjit-osr-enabling.js
new file mode 100644
index 0000000000..aaad2c32a4
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/enterjit-osr-enabling.js
@@ -0,0 +1,8 @@
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+(function() {
+ enableGeckoProfilingWithSlowAssertions();
+ var n = 50;
+ while (n--);
+})();
diff --git a/js/src/jit-test/tests/profiler/enterjit-osr.js b/js/src/jit-test/tests/profiler/enterjit-osr.js
new file mode 100644
index 0000000000..b490fafc96
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/enterjit-osr.js
@@ -0,0 +1,8 @@
+setJitCompilerOption("baseline.warmup.trigger", 10);
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+enableGeckoProfilingWithSlowAssertions();
+(function() {
+ var n = 50;
+ while (n--);
+})();
diff --git a/js/src/jit-test/tests/profiler/exception-unwind-hook.js b/js/src/jit-test/tests/profiler/exception-unwind-hook.js
new file mode 100644
index 0000000000..6b52d1615d
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/exception-unwind-hook.js
@@ -0,0 +1,22 @@
+// Test interaction between exception handler, debugger's onExceptionUnwind,
+// and profiler's frame iterator.
+
+var g = newGlobal({newCompartment: true});
+var dbg = new Debugger(g);
+
+g.eval("" + function f() {
+ for (var i = 0; i < 120; i++) {
+ try { throw 1; } catch {}
+ }
+});
+
+var count = 0;
+dbg.onExceptionUnwind = function() {
+ enableGeckoProfiling();
+ readGeckoProfilingStack();
+ disableGeckoProfiling();
+ count++;
+};
+
+g.f();
+assertEq(count, 120);
diff --git a/js/src/jit-test/tests/profiler/getter-setter-ic.js b/js/src/jit-test/tests/profiler/getter-setter-ic.js
new file mode 100644
index 0000000000..225d69895e
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/getter-setter-ic.js
@@ -0,0 +1,32 @@
+// Ensure readGeckoProfilingStack() doesn't crash with Ion
+// getter/setter ICs on the stack.
+function getObjects() {
+ var objs = [];
+ objs.push({x: 0, get prop() {
+ readGeckoProfilingStack();
+ return ++this.x;
+ }, set prop(v) {
+ readGeckoProfilingStack();
+ this.x = v + 2;
+ }});
+ objs.push({x: 0, y: 0, get prop() {
+ readGeckoProfilingStack();
+ return this.y;
+ }, set prop(v) {
+ readGeckoProfilingStack();
+ this.y = v;
+ }});
+ return objs;
+}
+function f() {
+ var objs = getObjects();
+ var res = 0;
+ for (var i=0; i<100; i++) {
+ var o = objs[i % objs.length];
+ res += o.prop;
+ o.prop = i;
+ }
+ assertEq(res, 4901);
+}
+enableGeckoProfiling();
+f();
diff --git a/js/src/jit-test/tests/profiler/interpreter-stacks.js b/js/src/jit-test/tests/profiler/interpreter-stacks.js
new file mode 100644
index 0000000000..71ebb681a8
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/interpreter-stacks.js
@@ -0,0 +1,105 @@
+// |jit-test| --no-blinterp
+// Disable Baseline Interpreter and JITs because we only read information about
+// C++ Interpreter profiling frames.
+
+enableGeckoProfilingWithSlowAssertions();
+
+function assertStack(stack, expected) {
+ assertEq(stack.length, expected.length);
+ for (let i = 0; i < stack.length; i++) {
+ // Use |split| to get rid of the file name.
+ assertEq(stack[i].dynamicString.split(" (")[0], expected[i]);
+ }
+}
+
+// We currently don't push entries for frames that were already on the stack
+// when the profiler was enabled.
+assertStack(readGeckoInterpProfilingStack(), []);
+
+function testBasic() {
+ let g1 = function() {
+ return readGeckoInterpProfilingStack();
+ }
+ let f1 = () => g1();
+ assertStack(f1(), ["testBasic", "f1", "g1"]);
+
+ // Test non-function frames.
+ assertStack(evaluate("eval(`(function foo() { return readGeckoInterpProfilingStack(); })()`)"),
+ ["testBasic", "@evaluate", "@evaluate line 1 > eval:1:0", "foo"]);
+}
+testBasic();
+testBasic();
+
+function testThrow() {
+ let stacks = [];
+ let thrower = function() {
+ stacks.push(readGeckoInterpProfilingStack());
+ throw 1;
+ };
+ let catcher = function() {
+ try {
+ thrower();
+ } catch (e) {
+ stacks.push(readGeckoInterpProfilingStack());
+ }
+ };
+ catcher();
+ assertEq(stacks.length, 2);
+ assertStack(stacks[0], ["testThrow", "catcher", "thrower"]);
+ assertStack(stacks[1], ["testThrow", "catcher"]);
+}
+testThrow();
+testThrow();
+
+function testSelfHosted() {
+ let stacks = [1, 2, 3].map(function() {
+ return readGeckoInterpProfilingStack();
+ });
+ assertEq(stacks.length, 3);
+ for (var stack of stacks) {
+ assertStack(stack, ["testSelfHosted", "map", "testSelfHosted/stacks<"]);
+ }
+}
+testSelfHosted();
+testSelfHosted();
+
+function testGenerator() {
+ let stacks = [];
+ let generator = function*() {
+ stacks.push(readGeckoInterpProfilingStack());
+ yield 1;
+ stacks.push(readGeckoInterpProfilingStack());
+ yield 2;
+ stacks.push(readGeckoInterpProfilingStack());
+ };
+ for (let x of generator()) {}
+ assertStack(readGeckoInterpProfilingStack(), ["testGenerator"]);
+
+ assertEq(stacks.length, 3);
+ for (var stack of stacks) {
+ assertStack(stack, ["testGenerator", "next", "generator"]);
+ }
+}
+testGenerator();
+testGenerator();
+
+async function testAsync() {
+ let stacks = [];
+ let asyncFun = async function() {
+ stacks.push(readGeckoInterpProfilingStack());
+ await 1;
+ stacks.push(readGeckoInterpProfilingStack());
+ };
+ await asyncFun();
+ assertStack(readGeckoInterpProfilingStack(), ["AsyncFunctionNext", "testAsync"]);
+
+ assertEq(stacks.length, 2);
+ assertStack(stacks[0], ["testAsync", "asyncFun"]);
+ assertStack(stacks[1], ["AsyncFunctionNext", "asyncFun"]);
+}
+testAsync();
+drainJobQueue();
+testAsync();
+drainJobQueue();
+
+disableGeckoProfiling();
diff --git a/js/src/jit-test/tests/profiler/ion-rectifier-frame-bug1530351.js b/js/src/jit-test/tests/profiler/ion-rectifier-frame-bug1530351.js
new file mode 100644
index 0000000000..651b635179
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/ion-rectifier-frame-bug1530351.js
@@ -0,0 +1,6 @@
+function test(str) {
+ for (let i = 0; i < 100; ++i)
+ Reflect.apply(String.prototype.substring, str, [])
+}
+enableGeckoProfilingWithSlowAssertions();
+test("");
diff --git a/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-1.js b/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-1.js
new file mode 100644
index 0000000000..f8e2f1f3d7
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-1.js
@@ -0,0 +1,10 @@
+// |jit-test| error:ReferenceError
+
+enableGeckoProfiling("Math.round", "-0.49", -0);
+function* g(n) {
+ for (var i = 0; i < n; i++) yield i;
+}
+var inner = g(20);
+for (let target of inner) {
+ if (GeneratorObjectPrototype() == i(true, true) == (this) == (this)) {}
+}
diff --git a/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-2.js b/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-2.js
new file mode 100644
index 0000000000..98e1ee0817
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/jsop-resume-return-bug1451385-2.js
@@ -0,0 +1,9 @@
+// |jit-test| error:ReferenceError
+
+function* g(n) {
+ for (var i = 0; i < n; i++) yield i;
+}
+var inner = g(20);
+for (let target of inner) {
+ if (GeneratorObjectPrototype() == i(true, true) == (this) == (this)) {}
+}
diff --git a/js/src/jit-test/tests/profiler/pc-count-profiler.js b/js/src/jit-test/tests/profiler/pc-count-profiler.js
new file mode 100644
index 0000000000..235055af3b
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/pc-count-profiler.js
@@ -0,0 +1,53 @@
+// Smoke test for the PC count profiler.
+
+function f(x) {
+ if (x < 10)
+ return 0;
+ if (x < 50)
+ return 1;
+ return 2;
+}
+
+L: try {
+ // Profile the test function "f".
+ pccount.start();
+ for (var i = 0; i < 100; ++i) f(i);
+ pccount.stop();
+
+ // Count the profiled scripts, stop if no scripts were profiled.
+ var n = pccount.count();
+ if (n === 0)
+ break L;
+
+ // Find the script index for "f".
+ var scriptIndex = -1;
+ for (var i = 0; i < n; ++i) {
+ var summary = JSON.parse(pccount.summary(i));
+ if (summary.name === "f")
+ scriptIndex = i;
+ }
+
+ // Stop if the script index for "f" wasn't found.
+ if (scriptIndex < 0)
+ break L;
+
+ // Retrieve the profiler data for "f".
+ var contents = pccount.contents(scriptIndex);
+ assertEq(typeof contents, "string");
+
+ // The profiler data should be parsable as JSON text.
+ var contents = JSON.parse(contents, (name, value) => {
+ // Split the Ion code segments into multiple entries.
+ if (name === "code")
+ return value.split("\n");
+
+ return value;
+ });
+
+ // Pretty print the profiler data.
+ var pretty = JSON.stringify(contents, null, 1);
+ print(pretty);
+} finally {
+ // Clean-up.
+ pccount.purge();
+}
diff --git a/js/src/jit-test/tests/profiler/test-baseline-eval-frame-profiling.js b/js/src/jit-test/tests/profiler/test-baseline-eval-frame-profiling.js
new file mode 100644
index 0000000000..fafa9a12d9
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/test-baseline-eval-frame-profiling.js
@@ -0,0 +1,11 @@
+
+setJitCompilerOption("baseline.warmup.trigger", 10);
+
+function main() {
+ for (var i = 0; i < 50; i++)
+ eval("for (var j = 0; j < 50; j++) readGeckoProfilingStack();");
+}
+
+gczeal(2, 10000);
+enableGeckoProfilingWithSlowAssertions();
+main();
diff --git a/js/src/jit-test/tests/profiler/test-bug1026485.js b/js/src/jit-test/tests/profiler/test-bug1026485.js
new file mode 100644
index 0000000000..4d0acc9c4c
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/test-bug1026485.js
@@ -0,0 +1,15 @@
+
+function TestCase(n, d, e, a) {
+ return TestCase.prototype.dump = function () {};
+}
+enableGeckoProfiling();
+new TestCase(typeof Number(new Number()));
+new TestCase(typeof Number(new Number(Number.NaN)));
+test();
+function test() {
+ try {
+ test();
+ } catch (e) {
+ new TestCase();
+ }
+}