diff options
Diffstat (limited to 'js/src/jit-test/tests/xdr/lazy.js')
-rw-r--r-- | js/src/jit-test/tests/xdr/lazy.js | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/xdr/lazy.js b/js/src/jit-test/tests/xdr/lazy.js new file mode 100644 index 000000000..da9d745fc --- /dev/null +++ b/js/src/jit-test/tests/xdr/lazy.js @@ -0,0 +1,164 @@ +load(libdir + 'bytecode-cache.js'); +var test = ""; +var checkAfter; + +// code a function which has both used and unused inner functions. +test = (function () { + function f(x) { + function ifTrue() { + return true; + }; + function ifFalse() { + return false; + }; + + if (x) return ifTrue(); + else return ifFalse(); + } + + return f.toSource() + "; f(true)"; +})(); +evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); + +// code a function which uses different inner functions based on the generation. +test = (function () { + function f(x) { + function ifTrue() { + return true; + }; + function ifFalse() { + return false; + }; + + if (x) return ifTrue(); + else return ifFalse(); + } + + return f.toSource() + "; f((generation % 2) == 0)"; +})(); +evalWithCache(test, { }); + +// Code a function which has an enclosing scope. +test = (function () { + function f() { + var upvar = ""; + function g() { upvar += ""; return upvar; } + return g; + } + + return f.toSource() + "; f()();"; +})(); +evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); + +// Code a lazy function which has an enclosing scope. +test = (function () { + function f() { + var upvar = ""; + function g() { upvar += ""; return upvar; } + return g; + } + + return f.toSource() + "; f();"; +})(); +evalWithCache(test, { assertEqBytecode: true }); + +// (basic/bug535930) Code an enclosing scope which is a Call object. +test = (function () { + return "(" + (function () { + p = function () { + Set() + }; + var Set = function () {}; + for (var x = 0; x < 5; x++) { + Set = function (z) { + return function () { + [z] + } + } (x) + } + }).toSource() + ")()"; +})(); +evalWithCache(test, { assertEqBytecode: true }); + +// Code an arrow function, and execute it. +test = (function () { + function f() { + var g = (a) => a + a; + return g; + } + + return f.toSource() + "; f()(1);"; +})(); +evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); + +// Code an arrow function, and do not execute it. +test = (function () { + function f() { + var g = (a) => a + a; + return g; + } + + return f.toSource() + "; f();"; +})(); +evalWithCache(test, { assertEqBytecode: true }); + +// Extra zeal GCs can cause isRelazifiableFunction() to become true after we +// record its value by throwing away JIT code for the function. +gczeal(0); + +// Ensure that decoded functions can be relazified. +test = "function f() { }; f();" + + "assertEq(isLazyFunction(f), false);" + + "var expect = isRelazifiableFunction(f);"; +checkAfter = function (ctx) { + gc(ctx.global.f, "shrinking"); // relazify f, if possible. + evaluate("assertEq(isLazyFunction(f), expect);", ctx); +}; +evalWithCache(test, { + assertEqBytecode: true, // Check that we re-encode the same thing. + assertEqResult: true, // The function should remain relazifiable, if it was + // during the first run. + checkAfter: checkAfter // Check that relazifying the restored function works + // if the original was relazifiable. +}); + +// Ensure that decoded functions can be relazified, even if they have free +// variables. +test = "function f() { return isRelazifiableFunction(f) }; var expect = f();" + + "assertEq(isLazyFunction(f), false);" + + "expect"; +checkAfter = function (ctx) { + gc(ctx.global.f, "shrinking"); // relazify f, if possible. + evaluate("assertEq(isLazyFunction(f), expect);", ctx); +}; +evalWithCache(test, { + assertEqBytecode: true, // Check that we re-encode the same thing. + assertEqResult: true, // The function should remain relazifiable, if it was + // during the first run. + checkAfter: checkAfter // Check that relazifying the restored function works + // if the original was relazifiable. +}); + +// Ensure that if a function is encoded when non-lazy but relazifiable, then +// decoded, relazified, and then delazified, the result actually works. +test = ` + function f() { return true; }; + var canBeLazy = isRelazifiableFunction(f) || isLazyFunction(f); + relazifyFunctions(); + assertEq(isLazyFunction(f), canBeLazy); + f()` +evalWithCache(test, { assertEqBytecode: true, assertEqResult: true }); + +// And more of the same, in a slightly different way +var g1 = newGlobal({ cloneSingletons: true }); +var g2 = newGlobal(); +var res = "function f(){}"; +var code = cacheEntry(res + "; f();"); +evaluate(code, {global:g1, compileAndGo: true, saveBytecode: {value: true}}); +evaluate(code, {global:g2, loadBytecode: true}); +gc(); +assertEq(g2.f.toString(), res); + +// Another relazification case. +var src = "function f() { return 3; }; f(); relazifyFunctions(); 4"; +evalWithCache(src, {assertEqBytecode: true, assertEqResult: true}); |