mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 716647 - Part 6: Tests. (r=jimb)
This commit is contained in:
parent
51af97477a
commit
34f8bd3c53
69
js/src/jit-test/lib/jitopts.js
Normal file
69
js/src/jit-test/lib/jitopts.js
Normal file
@ -0,0 +1,69 @@
|
||||
// These predicates are for tests that require a particular set of JIT options.
|
||||
|
||||
// Check if toggles match. Useful for tests that shouldn't be run if a
|
||||
// different set of JIT toggles are set, since TBPL runs each jit-test
|
||||
// multiple times with a variety of flags.
|
||||
function jitTogglesMatch(opts) {
|
||||
var currentOpts = getJitCompilerOptions();
|
||||
for (var k in opts) {
|
||||
if (k.indexOf(".enable") > 0 && opts[k] != currentOpts[k])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Run fn under a particular set of JIT options.
|
||||
function withJitOptions(opts, fn) {
|
||||
var oldOpts = getJitCompilerOptions();
|
||||
for (var k in opts)
|
||||
setJitCompilerOption(k, opts[k]);
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
for (var k in oldOpts)
|
||||
setJitCompilerOption(k, oldOpts[k]);
|
||||
}
|
||||
}
|
||||
|
||||
// N.B. Ion opts *must come before* baseline opts because there's some kind of
|
||||
// "undo eager compilation" logic. If we don't set the baseline usecount
|
||||
// *after* the Ion usecount we end up setting the baseline usecount to be the
|
||||
// default if we hit the "undo eager compilation" logic.
|
||||
var Opts_BaselineEager =
|
||||
{
|
||||
'ion.enable': 1,
|
||||
'baseline.enable': 1,
|
||||
'baseline.usecount.trigger': 0,
|
||||
'parallel-compilation.enable': 1
|
||||
};
|
||||
|
||||
// Checking for parallel compilation being off is often helpful if the test
|
||||
// requires a function be Ion compiled. Each individual test will usually
|
||||
// finish before the Ion compilation thread has a chance to attach the
|
||||
// compiled code.
|
||||
var Opts_IonEagerNoParallelCompilation =
|
||||
{
|
||||
'ion.enable': 1,
|
||||
'ion.usecount.trigger': 0,
|
||||
'baseline.enable': 1,
|
||||
'baseline.usecount.trigger': 0,
|
||||
'parallel-compilation.enable': 0,
|
||||
};
|
||||
|
||||
var Opts_Ion2NoParallelCompilation =
|
||||
{
|
||||
'ion.enable': 1,
|
||||
'ion.usecount.trigger': 2,
|
||||
'baseline.enable': 1,
|
||||
'baseline.usecount.trigger': 1,
|
||||
'parallel-compilation.enable': 0
|
||||
};
|
||||
|
||||
var Opts_NoJits =
|
||||
{
|
||||
'ion.enable': 0,
|
||||
'ion.usecount.trigger': 0,
|
||||
'baseline.usecount.trigger': 0,
|
||||
'baseline.enable': 0,
|
||||
'parallel-compilation.enable': 0
|
||||
};
|
24
js/src/jit-test/tests/debug/Debugger-debuggees-22.js
Normal file
24
js/src/jit-test/tests/debug/Debugger-debuggees-22.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Adding a debuggee allowed with scripts on stack.
|
||||
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
g(d);
|
||||
if (d)
|
||||
assertEq(dbg.hasDebuggee(this), true);
|
||||
});
|
||||
|
||||
g.eval("" + function g(d) {
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
dbg.addDebuggee(this);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f(false);
|
||||
f(false);
|
||||
f(true);
|
||||
f(true);
|
||||
} + ")();");
|
107
js/src/jit-test/tests/debug/Debugger-debuggees-23.js
Normal file
107
js/src/jit-test/tests/debug/Debugger-debuggees-23.js
Normal file
@ -0,0 +1,107 @@
|
||||
// Adding a debuggee allowed with scripts on stack from stranger places.
|
||||
|
||||
// Test CCW.
|
||||
(function testCCW() {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
g.dbg = dbg;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.turnOnDebugger = function () {
|
||||
dbg.addDebuggee(g);
|
||||
};
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
turnOnDebugger();
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f(false);
|
||||
f(false);
|
||||
f(true);
|
||||
f(true);
|
||||
} + ")();");
|
||||
})();
|
||||
|
||||
// Test getter.
|
||||
(function testGetter() {
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.eval("" + function f(obj) {
|
||||
obj.foo;
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f({ get foo() { dbg.addDebuggee(GLOBAL); } });
|
||||
} + ")();");
|
||||
})();
|
||||
|
||||
// Test setter.
|
||||
(function testSetter() {
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.eval("" + function f(obj) {
|
||||
obj.foo = 42;
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f({ set foo(v) { dbg.addDebuggee(GLOBAL); } });
|
||||
} + ")();");
|
||||
})();
|
||||
|
||||
// Test toString.
|
||||
(function testToString() {
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.eval("" + function f(obj) {
|
||||
obj + "";
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f({ toString: function () { dbg.addDebuggee(GLOBAL); }});
|
||||
} + ")();");
|
||||
})();
|
||||
|
||||
// Test valueOf.
|
||||
(function testValueOf() {
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.eval("" + function f(obj) {
|
||||
obj + "";
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
f({ valueOf: function () { dbg.addDebuggee(GLOBAL); }});
|
||||
} + ")();");
|
||||
})();
|
||||
|
||||
// Test proxy trap.
|
||||
(function testProxyTrap() {
|
||||
var g = newGlobal();
|
||||
g.dbg = new Debugger;
|
||||
g.GLOBAL = g;
|
||||
|
||||
g.eval("" + function f(proxy) {
|
||||
proxy["foo"];
|
||||
assertEq(dbg.hasDebuggee(GLOBAL), true);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
var handler = { get: function () { dbg.addDebuggee(GLOBAL); } };
|
||||
var proxy = new Proxy({}, handler);
|
||||
f(proxy);
|
||||
} + ")();");
|
||||
})();
|
55
js/src/jit-test/tests/debug/Debugger-debuggees-24.js
Normal file
55
js/src/jit-test/tests/debug/Debugger-debuggees-24.js
Normal file
@ -0,0 +1,55 @@
|
||||
// Turning debugger on for a particular global with on-stack scripts shouldn't
|
||||
// make other globals' scripts observable.
|
||||
|
||||
var g1 = newGlobal();
|
||||
var g2 = newGlobal();
|
||||
var g3 = newGlobal();
|
||||
|
||||
g1.eval("" + function f() {
|
||||
var name = "f";
|
||||
g();
|
||||
return name;
|
||||
});
|
||||
g2.eval("" + function g() {
|
||||
var name = "g";
|
||||
h();
|
||||
return name;
|
||||
});
|
||||
g3.eval("" + function h() {
|
||||
var name = "h";
|
||||
toggle();
|
||||
return name;
|
||||
});
|
||||
|
||||
g1.g = g2.g;
|
||||
g2.h = g3.h;
|
||||
|
||||
function name(f) {
|
||||
return f.environment.getVariable("name");
|
||||
}
|
||||
|
||||
var dbg = new Debugger;
|
||||
g3.toggle = function () {
|
||||
var frame;
|
||||
|
||||
// Only f should be visible.
|
||||
dbg.addDebuggee(g1);
|
||||
frame = dbg.getNewestFrame();
|
||||
assertEq(name(frame), "f");
|
||||
|
||||
// Now h should also be visible.
|
||||
dbg.addDebuggee(g3);
|
||||
frame = dbg.getNewestFrame();
|
||||
assertEq(name(frame), "h");
|
||||
assertEq(name(frame.older), "f");
|
||||
|
||||
// Finally everything should be visible.
|
||||
dbg.addDebuggee(g2);
|
||||
frame = dbg.getNewestFrame();
|
||||
assertEq(name(frame), "h");
|
||||
assertEq(name(frame.older), "g");
|
||||
assertEq(name(frame.older.older), "f");
|
||||
};
|
||||
|
||||
g1.eval("(" + function () { f(); } + ")();");
|
||||
|
48
js/src/jit-test/tests/debug/Debugger-debuggees-25.js
Normal file
48
js/src/jit-test/tests/debug/Debugger-debuggees-25.js
Normal file
@ -0,0 +1,48 @@
|
||||
// Turning debugger off global at a time.
|
||||
|
||||
var g1 = newGlobal();
|
||||
var g2 = newGlobal();
|
||||
var g3 = newGlobal();
|
||||
|
||||
g1.eval("" + function f() {
|
||||
var name = "f";
|
||||
g();
|
||||
return name;
|
||||
});
|
||||
g2.eval("" + function g() {
|
||||
var name = "g";
|
||||
h();
|
||||
return name;
|
||||
});
|
||||
g3.eval("" + function h() {
|
||||
var name = "h";
|
||||
toggle();
|
||||
return name;
|
||||
});
|
||||
|
||||
g1.g = g2.g;
|
||||
g2.h = g3.h;
|
||||
|
||||
function name(f) {
|
||||
return f.environment.getVariable("name");
|
||||
}
|
||||
|
||||
var dbg = new Debugger;
|
||||
g3.toggle = function () {
|
||||
var frame;
|
||||
|
||||
// Add all globals.
|
||||
dbg.addDebuggee(g1);
|
||||
dbg.addDebuggee(g3);
|
||||
dbg.addDebuggee(g2);
|
||||
|
||||
// Remove one at a time.
|
||||
dbg.removeDebuggee(g3);
|
||||
assertEq(name(dbg.getNewestFrame()), "g");
|
||||
dbg.removeDebuggee(g2);
|
||||
assertEq(name(dbg.getNewestFrame()), "f");
|
||||
dbg.removeDebuggee(g1);
|
||||
};
|
||||
|
||||
g1.eval("(" + function () { f(); } + ")();");
|
||||
|
34
js/src/jit-test/tests/debug/Debugger-debuggees-26.js
Normal file
34
js/src/jit-test/tests/debug/Debugger-debuggees-26.js
Normal file
@ -0,0 +1,34 @@
|
||||
// Ion can bail in-place when throwing exceptions with debug mode toggled on.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit();
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.toggle = function toggle(x, d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var frame = dbg.getNewestFrame().older;
|
||||
assertEq(frame.callee.name, "f");
|
||||
assertEq(frame.implementation, "ion");
|
||||
throw 42;
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(x, d) { g(x, d); });
|
||||
g.eval("" + function g(x, d) { toggle(x, d); });
|
||||
|
||||
try {
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(42, false);
|
||||
f(42, true);
|
||||
} + ")();");
|
||||
} catch (exc) {
|
||||
assertEq(exc, 42);
|
||||
}
|
||||
});
|
30
js/src/jit-test/tests/debug/Frame-eval-19.js
Normal file
30
js/src/jit-test/tests/debug/Frame-eval-19.js
Normal file
@ -0,0 +1,30 @@
|
||||
// Eval-in-frame of optimized frames to break out of an infinite loop.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit(0);
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.eval("" + function f(d) { g(d); });
|
||||
g.eval("" + function g(d) { h(d); });
|
||||
g.eval("" + function h(d) { while (d); });
|
||||
|
||||
timeout(5, function () {
|
||||
dbg.addDebuggee(g);
|
||||
var frame = dbg.getNewestFrame();
|
||||
if (frame.callee.name != "h" || frame.implementation != "ion")
|
||||
return true;
|
||||
frame.eval("d = false;");
|
||||
return true;
|
||||
});
|
||||
|
||||
g.eval("(" + function () {
|
||||
for (i = 0; i < 5; i++)
|
||||
f(false);
|
||||
f(true);
|
||||
} + ")();");
|
||||
});
|
46
js/src/jit-test/tests/debug/Frame-eval-20.js
Normal file
46
js/src/jit-test/tests/debug/Frame-eval-20.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Eval-in-frame with different type on non-youngest Ion frame.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit(0);
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
function test(shadow) {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
// Note that we depend on CCW scripted functions being opaque to Ion
|
||||
// optimization for this test.
|
||||
g.h = function h(d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var f = dbg.getNewestFrame().older;
|
||||
assertEq(f.implementation, "ion");
|
||||
assertEq(f.environment.getVariable("foo"), 42);
|
||||
|
||||
// EIF of a different type too.
|
||||
f.eval((shadow ? "var " : "") + "foo = 'string of 42'");
|
||||
g.expected = shadow ? 42 : "string of 42";
|
||||
}
|
||||
}
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
var foo = 42;
|
||||
g(d);
|
||||
return foo;
|
||||
});
|
||||
g.eval("" + function g(d) {
|
||||
h(d);
|
||||
});
|
||||
|
||||
g.eval("(" + function () {
|
||||
for (i = 0; i < 5; i++)
|
||||
f(false);
|
||||
assertEq(f(true), "string of 42");
|
||||
} + ")();");
|
||||
}
|
||||
|
||||
test(false);
|
||||
test(true);
|
||||
});
|
33
js/src/jit-test/tests/debug/Frame-eval-21.js
Normal file
33
js/src/jit-test/tests/debug/Frame-eval-21.js
Normal file
@ -0,0 +1,33 @@
|
||||
// Eval-in-frame with different type on baseline frame with let-scoping
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_BaselineEager))
|
||||
quit(0);
|
||||
|
||||
withJitOptions(Opts_BaselineEager, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.h = function h(d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var f = dbg.getNewestFrame().older;
|
||||
assertEq(f.implementation, "baseline");
|
||||
assertEq(f.environment.getVariable("foo"), 42);
|
||||
f.eval("foo = 'string of 42'");
|
||||
}
|
||||
}
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
if (d) {
|
||||
let foo = 42;
|
||||
g(d);
|
||||
return foo;
|
||||
}
|
||||
});
|
||||
|
||||
g.eval("" + function g(d) { h(d); });
|
||||
|
||||
g.eval("(" + function () { assertEq(f(true), "string of 42"); } + ")();");
|
||||
});
|
32
js/src/jit-test/tests/debug/Frame-eval-22.js
Normal file
32
js/src/jit-test/tests/debug/Frame-eval-22.js
Normal file
@ -0,0 +1,32 @@
|
||||
// Debugger.Frame preserves Ion frame identity
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit();
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg1 = new Debugger;
|
||||
var dbg2 = new Debugger;
|
||||
|
||||
g.toggle = function toggle(x, d) {
|
||||
if (d) {
|
||||
dbg1.addDebuggee(g);
|
||||
dbg2.addDebuggee(g);
|
||||
var frame1 = dbg1.getNewestFrame();
|
||||
assertEq(frame1.environment.getVariable("x"), x);
|
||||
assertEq(frame1.implementation, "ion");
|
||||
frame1.environment.setVariable("x", "not 42");
|
||||
assertEq(dbg2.getNewestFrame().environment.getVariable("x"), "not 42");
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(x, d) { toggle(x, d); });
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(42, false);
|
||||
f(42, true);
|
||||
} + ")();");
|
||||
});
|
37
js/src/jit-test/tests/debug/Frame-eval-23.js
Normal file
37
js/src/jit-test/tests/debug/Frame-eval-23.js
Normal file
@ -0,0 +1,37 @@
|
||||
// Debugger.Frame preserves Ion frame mutations after removing debuggee.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit();
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.toggle = function toggle(x, d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var frame = dbg.getNewestFrame().older;
|
||||
assertEq(frame.callee.name, "f");
|
||||
assertEq(frame.environment.getVariable("x"), x);
|
||||
assertEq(frame.implementation, "ion");
|
||||
frame.environment.setVariable("x", "not 42");
|
||||
dbg.removeDebuggee(g);
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(x, d) {
|
||||
g(x, d);
|
||||
if (d)
|
||||
assertEq(x, "not 42");
|
||||
});
|
||||
|
||||
g.eval("" + function g(x, d) { toggle(x, d); });
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(42, false);
|
||||
f(42, true);
|
||||
} + ")();");
|
||||
});
|
45
js/src/jit-test/tests/debug/Frame-implementation-01.js
Normal file
45
js/src/jit-test/tests/debug/Frame-implementation-01.js
Normal file
@ -0,0 +1,45 @@
|
||||
// Debugger.Frames of all implementations.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
function testFrameImpl(jitopts, assertFrameImpl) {
|
||||
if (!jitTogglesMatch(jitopts))
|
||||
return;
|
||||
|
||||
withJitOptions(jitopts, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.toggle = function toggle(d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var frame = dbg.getNewestFrame();
|
||||
// We only care about the f and g frames.
|
||||
for (var i = 0; i < 2; i++) {
|
||||
assertFrameImpl(frame);
|
||||
frame = frame.older;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(d) { g(d); });
|
||||
g.eval("" + function g(d) { toggle(d); });
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(false);
|
||||
f(true);
|
||||
} + ")();");
|
||||
});
|
||||
}
|
||||
|
||||
[[Opts_BaselineEager,
|
||||
function (f) { assertEq(f.implementation, "baseline"); }],
|
||||
// Note that the Ion case *depends* on CCW scripted functions being opaque to
|
||||
// Ion optimization and not deoptimizing the frames below the call to toggle.
|
||||
[Opts_Ion2NoParallelCompilation,
|
||||
function (f) { assertEq(f.implementation, "ion"); }],
|
||||
[Opts_NoJits,
|
||||
function (f) { assertEq(f.implementation, "interpreter"); }]].forEach(function ([opts, fn]) {
|
||||
testFrameImpl(opts, fn);
|
||||
});
|
51
js/src/jit-test/tests/debug/Frame-implementation-02.js
Normal file
51
js/src/jit-test/tests/debug/Frame-implementation-02.js
Normal file
@ -0,0 +1,51 @@
|
||||
// Test that Ion frames are invalidated by turning on Debugger. Invalidation
|
||||
// is unobservable, but we know that Ion scripts cannot handle Debugger
|
||||
// handlers, so we test for the handlers being called.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit();
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
var onPopExecuted = false;
|
||||
var breakpointHit = false;
|
||||
|
||||
g.toggle = function toggle(d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
|
||||
var frame1 = dbg.getNewestFrame();
|
||||
assertEq(frame1.implementation, "ion");
|
||||
frame1.onPop = function () {
|
||||
onPopExecuted = true;
|
||||
};
|
||||
|
||||
var frame2 = frame1.older;
|
||||
assertEq(frame2.implementation, "ion");
|
||||
// Offset of |print(42 + 42)|
|
||||
var offset = frame2.script.getLineOffsets(3)[0];
|
||||
frame2.script.setBreakpoint(offset, { hit: function (fr) {
|
||||
assertEq(fr.implementation != "ion", true);
|
||||
breakpointHit = true;
|
||||
}});
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
g(d);
|
||||
print(42 + 42);
|
||||
});
|
||||
g.eval("" + function g(d) { toggle(d); });
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(false);
|
||||
f(true);
|
||||
} + ")();");
|
||||
|
||||
assertEq(onPopExecuted, true);
|
||||
assertEq(breakpointHit, true);
|
||||
});
|
42
js/src/jit-test/tests/debug/optimized-out-01.js
Normal file
42
js/src/jit-test/tests/debug/optimized-out-01.js
Normal file
@ -0,0 +1,42 @@
|
||||
// Tests that we can reflect optimized out values.
|
||||
//
|
||||
// Unfortunately these tests are brittle. They depend on opaque JIT heuristics
|
||||
// kicking in.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoParallelCompilation))
|
||||
quit(0);
|
||||
|
||||
withJitOptions(Opts_Ion2NoParallelCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
// Note that this *depends* on CCW scripted functions being opaque to Ion
|
||||
// optimization and not deoptimizing the frames below the call to toggle.
|
||||
g.toggle = function toggle(d) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
var frame = dbg.getNewestFrame();
|
||||
assertEq(frame.implementation, "ion");
|
||||
// x is unused and should be elided.
|
||||
assertEq(frame.environment.getVariable("x").optimizedOut, true);
|
||||
assertEq(frame.arguments[1].optimizedOut, true);
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(d, x) { g(d, x); });
|
||||
|
||||
g.eval("" + function g(d, x) {
|
||||
for (var i = 0; i < 200; i++);
|
||||
// Hack to prevent inlining.
|
||||
function inner() { i = 42; };
|
||||
toggle(d);
|
||||
});
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (i = 0; i < 5; i++)
|
||||
f(false, 42);
|
||||
f(true, 42);
|
||||
} + ")();");
|
||||
});
|
93
js/src/jit-test/tests/debug/resumption-08.js
Normal file
93
js/src/jit-test/tests/debug/resumption-08.js
Normal file
@ -0,0 +1,93 @@
|
||||
// Check whether we respect resumption values when toggling debug mode on->off
|
||||
// from various points with live scripts on the stack.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
function reset() {
|
||||
dbg.onEnterFrame = undefined;
|
||||
dbg.onDebuggerStatement = undefined;
|
||||
dbg.addDebuggee(g);
|
||||
g.eval("(" + function test() {
|
||||
for (i = 0; i < 5; i++)
|
||||
f(42);
|
||||
} + ")();");
|
||||
}
|
||||
|
||||
g.eval("" + function f(d) {
|
||||
return g(d);
|
||||
});
|
||||
|
||||
g.eval("" + function g(d) {
|
||||
debugger;
|
||||
return d;
|
||||
});
|
||||
|
||||
function testResumptionValues(handlerSetter) {
|
||||
// Test normal return.
|
||||
reset();
|
||||
handlerSetter(undefined);
|
||||
assertEq(g.eval("(" + function test() { return f(42); } + ")();"), 42);
|
||||
|
||||
// Test forced return.
|
||||
reset();
|
||||
handlerSetter({ return: "not 42" });
|
||||
assertEq(g.eval("(" + function test() { return f(42); } + ")();"), "not 42");
|
||||
|
||||
// Test throw.
|
||||
reset();
|
||||
handlerSetter({ throw: "thrown 42" });
|
||||
try {
|
||||
g.eval("(" + function test() { return f(42); } + ")();");;
|
||||
} catch (e) {
|
||||
assertEq(e, "thrown 42");
|
||||
}
|
||||
}
|
||||
|
||||
// Turn off from within the prologue.
|
||||
testResumptionValues(function (resumptionVal) {
|
||||
dbg.onEnterFrame = function (frame) {
|
||||
if (frame.older) {
|
||||
if (frame.older.older) {
|
||||
dbg.removeDebuggee(g);
|
||||
return resumptionVal;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Turn off from within the epilogue.
|
||||
testResumptionValues(function (resumptionVal) {
|
||||
dbg.onEnterFrame = function (frame) {
|
||||
if (frame.older) {
|
||||
if (frame.older.older) {
|
||||
frame.onPop = function () {
|
||||
dbg.removeDebuggee(g);
|
||||
return resumptionVal;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Turn off from within debugger statement handler.
|
||||
testResumptionValues(function (resumptionVal) {
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
dbg.removeDebuggee(g);
|
||||
return resumptionVal;
|
||||
};
|
||||
});
|
||||
|
||||
// Turn off from within debug trap handler.
|
||||
testResumptionValues(function (resumptionVal) {
|
||||
dbg.onEnterFrame = function (frame) {
|
||||
if (frame.older) {
|
||||
if (frame.older.older) {
|
||||
frame.onStep = function () {
|
||||
dbg.removeDebuggee(g);
|
||||
return resumptionVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
@ -6111,6 +6111,15 @@ JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t v
|
||||
IonSpew(js::jit::IonSpew_BaselineScripts, "Disable baseline");
|
||||
}
|
||||
break;
|
||||
case JSJITCOMPILER_PARALLEL_COMPILATION_ENABLE:
|
||||
if (value == 1) {
|
||||
rt->setParallelIonCompilationEnabled(true);
|
||||
IonSpew(js::jit::IonSpew_Scripts, "Enable parallel compilation");
|
||||
} else if (value == 0) {
|
||||
rt->setParallelIonCompilationEnabled(false);
|
||||
IonSpew(js::jit::IonSpew_Scripts, "Disable parallel compilation");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -6130,6 +6139,8 @@ JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt)
|
||||
return JS::RuntimeOptionsRef(rt).ion();
|
||||
case JSJITCOMPILER_BASELINE_ENABLE:
|
||||
return JS::RuntimeOptionsRef(rt).baseline();
|
||||
case JSJITCOMPILER_PARALLEL_COMPILATION_ENABLE:
|
||||
return rt->canUseParallelIonCompilation();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4631,11 +4631,12 @@ JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled);
|
||||
|
||||
#define JIT_COMPILER_OPTIONS(Register) \
|
||||
Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \
|
||||
Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
Register(BASELINE_ENABLE, "baseline.enable")
|
||||
#define JIT_COMPILER_OPTIONS(Register) \
|
||||
Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \
|
||||
Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
Register(BASELINE_ENABLE, "baseline.enable") \
|
||||
Register(PARALLEL_COMPILATION_ENABLE, "parallel-compilation.enable")
|
||||
|
||||
typedef enum JSJitCompilerOption {
|
||||
#define JIT_COMPILER_DECLARE(key, str) \
|
||||
|
Loading…
Reference in New Issue
Block a user