diff options
Diffstat (limited to 'js/src/jit-test/tests/gc')
205 files changed, 3687 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/gc/bug-1004457.js b/js/src/jit-test/tests/gc/bug-1004457.js new file mode 100644 index 000000000..80e1150f3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1004457.js @@ -0,0 +1,3 @@ +var argObj = (function () { return arguments })(); +gczeal(4); +delete argObj.callee; diff --git a/js/src/jit-test/tests/gc/bug-1016016.js b/js/src/jit-test/tests/gc/bug-1016016.js new file mode 100644 index 000000000..441794c6a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1016016.js @@ -0,0 +1,15 @@ +// |jit-test| error:ReferenceError +toPrinted(this.reason); +function toPrinted(value) + value = String(value); +var lfcode = new Array(); +lfcode.push = loadFile; +lfcode.push("enableTrackAllocations();"); +lfcode.push("\ +gczeal(9, 2);\ +newGlobal();\ +''.addDebuggee(g1);\ +"); +function loadFile(lfVarx) { + evaluate(lfVarx, { noScriptRval : true, isRunOnce : true }); +} diff --git a/js/src/jit-test/tests/gc/bug-1017141.js b/js/src/jit-test/tests/gc/bug-1017141.js new file mode 100644 index 000000000..9c4533924 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1017141.js @@ -0,0 +1,25 @@ +var min = gcparam('minEmptyChunkCount'); +var max = gcparam('maxEmptyChunkCount'); + +gcparam('minEmptyChunkCount', 10); +gcparam('maxEmptyChunkCount', 20); +assertEq(gcparam('minEmptyChunkCount'), 10); +assertEq(gcparam('maxEmptyChunkCount'), 20); +gc(); + +/* We maintain the invariant that maxEmptyChunkCount >= minEmptyChunkCount. */ +gcparam('minEmptyChunkCount', 30); +assertEq(gcparam('minEmptyChunkCount'), 30); +assertEq(gcparam('maxEmptyChunkCount'), 30); +gc(); + +gcparam('maxEmptyChunkCount', 5); +assertEq(gcparam('minEmptyChunkCount'), 5); +assertEq(gcparam('maxEmptyChunkCount'), 5); +gc(); + +gcparam('minEmptyChunkCount', min); +gcparam('maxEmptyChunkCount', max); +assertEq(gcparam('minEmptyChunkCount'), min); +assertEq(gcparam('maxEmptyChunkCount'), max); +gc(); diff --git a/js/src/jit-test/tests/gc/bug-1028863.js b/js/src/jit-test/tests/gc/bug-1028863.js new file mode 100644 index 000000000..699c02fb7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1028863.js @@ -0,0 +1,3 @@ +function writeTestCaseResult( expect, actual, string ) {} +schedulegc(10); +if (saveStack() == 3) done = true; diff --git a/js/src/jit-test/tests/gc/bug-1032206.js b/js/src/jit-test/tests/gc/bug-1032206.js new file mode 100644 index 000000000..c58cc53a8 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1032206.js @@ -0,0 +1,3 @@ +gczeal(4); +var symbols = [Symbol(), Symbol("comet"), Symbol.for("moon"), Symbol.iterator, 0]; +for (var a of symbols) {} diff --git a/js/src/jit-test/tests/gc/bug-1035371.js b/js/src/jit-test/tests/gc/bug-1035371.js new file mode 100644 index 000000000..b42a74656 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1035371.js @@ -0,0 +1,4 @@ +x = function() {}; +y = new WeakMap; +selectforgc({});; +y.set(x, Symbol()); diff --git a/js/src/jit-test/tests/gc/bug-1039516.js b/js/src/jit-test/tests/gc/bug-1039516.js new file mode 100644 index 000000000..15f2a994d --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1039516.js @@ -0,0 +1,6 @@ +gczeal(9); +Symbol.for("a"); +gcslice(1); +var a = Symbol.for("a"); +gcslice(); +print(Symbol.keyFor(a)); diff --git a/js/src/jit-test/tests/gc/bug-1053676.js b/js/src/jit-test/tests/gc/bug-1053676.js new file mode 100644 index 000000000..3b3b0b117 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1053676.js @@ -0,0 +1,12 @@ +// |jit-test| --ion-eager; +if (typeof Symbol !== "function") quit(0); + +var x +(function() { + x +}()); +verifyprebarriers(); +x = x * 0 +x = Symbol(); +gc(); +evalcx("x=1", this); diff --git a/js/src/jit-test/tests/gc/bug-1055219.js b/js/src/jit-test/tests/gc/bug-1055219.js new file mode 100644 index 000000000..421aa55ae --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1055219.js @@ -0,0 +1,5 @@ +gczeal(13); +function A() {}; +A.prototype = []; +function B() {}; +B.prototype = new A(); diff --git a/js/src/jit-test/tests/gc/bug-1070638.js b/js/src/jit-test/tests/gc/bug-1070638.js new file mode 100644 index 000000000..23793765c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1070638.js @@ -0,0 +1,20 @@ +function m() { + for (var j = 0; j < 99; ++j) { + for (var k = 0; k < 99; ++k) { + try { + undefined()() + } catch (e) {} + } + } +} +m() +m() +m() +m() +for (var j = 0; j < 99; ++j) { + for (var k = 0; k < 99; ++k) { + try { + gcslice(1)() + } catch (e) {} + } +} diff --git a/js/src/jit-test/tests/gc/bug-1075546.js b/js/src/jit-test/tests/gc/bug-1075546.js new file mode 100644 index 000000000..001e764ea --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1075546.js @@ -0,0 +1,30 @@ +for (var i = 0; i < 200; ++i) { + Object.getOwnPropertyNames(undefined + ""); +} +function p(s) { + for (var i = 0; i < s.length; i++) { + s.charCodeAt(i); + } +} +function m(f) { + var a = []; + for (var j = 0; j < 700; ++j) { + try { + f() + } catch (e) { + a.push(e.toString()); + } + } + p(uneval(a)); +} +f = Function("\ + function f() {\ + functionf\n{}\ + }\ + m(f);\ +"); +f(); +f(); +for (var x = 0; x < 99; x++) { + newGlobal() +} diff --git a/js/src/jit-test/tests/gc/bug-1104162.js b/js/src/jit-test/tests/gc/bug-1104162.js new file mode 100644 index 000000000..0ccc63c60 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1104162.js @@ -0,0 +1,7 @@ +gczeal(11); +g = newGlobal() +g.eval("undefined;function f(){}") +Debugger(g).onDebuggerStatement = function(x) { + x.eval("f").return.script.setBreakpoint(0, {}) +} +g.eval("debugger") diff --git a/js/src/jit-test/tests/gc/bug-1108007.js b/js/src/jit-test/tests/gc/bug-1108007.js new file mode 100644 index 000000000..2ee1864c5 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1108007.js @@ -0,0 +1,24 @@ +// |jit-test| --no-threads; --no-ion; --no-baseline +if (!("gczeal" in this)) + quit(); +gczeal(2); +(function() { + evaluate(cacheEntry((function() { + return "".toSource() + })()), Object.create({ global: newGlobal({ cloneSingletons: true }) }, { + saveBytecode: { + value: true + } + })) +})(); +[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], + [0], [0], [0], [0]]; diff --git a/js/src/jit-test/tests/gc/bug-1108836.js b/js/src/jit-test/tests/gc/bug-1108836.js new file mode 100644 index 000000000..e8d32b3e3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1108836.js @@ -0,0 +1,9 @@ +const root = newGlobal(); +var g = newGlobal(); +for (var indexI = 0; indexI <= 65535; indexI++) { + eval("/*var " + String.fromCharCode(indexI) + "xx = 1*/"); +} +for (var i = 0; i < 100; ++i) { + gc(); + gcslice(1000000); +} diff --git a/js/src/jit-test/tests/gc/bug-1109913.js b/js/src/jit-test/tests/gc/bug-1109913.js new file mode 100644 index 000000000..a53428c44 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1109913.js @@ -0,0 +1,7 @@ +// |jit-test| error: out of memory + +gcparam("maxBytes", gcparam("gcBytes")); +eval(` + gczeal(2, 1); + newGlobal(); +`); diff --git a/js/src/jit-test/tests/gc/bug-1109922.js b/js/src/jit-test/tests/gc/bug-1109922.js new file mode 100644 index 000000000..8bd5c52da --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1109922.js @@ -0,0 +1,6 @@ +if (this.hasOwnProperty("Intl")) { + gczeal(14); + b = {}; + b.__proto__ = evalcx("lazy"); + (function m(b) {})(b.Intl.Collator(0)) +} diff --git a/js/src/jit-test/tests/gc/bug-1123648.js b/js/src/jit-test/tests/gc/bug-1123648.js new file mode 100644 index 000000000..7eb23900f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1123648.js @@ -0,0 +1,5 @@ +if (!("ctypes" in this)) + quit(); + +gczeal(14, 1); +ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []).ptr; diff --git a/js/src/jit-test/tests/gc/bug-1124563.js b/js/src/jit-test/tests/gc/bug-1124563.js new file mode 100644 index 000000000..73599025b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1124563.js @@ -0,0 +1,4 @@ +try { + gc(0, 'shrinking')({x: 0}) +} catch (e) {} +eval("({x: 0, x: 0})[{x: 0}]") diff --git a/js/src/jit-test/tests/gc/bug-1124653.js b/js/src/jit-test/tests/gc/bug-1124653.js new file mode 100644 index 000000000..8dca8dc33 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1124653.js @@ -0,0 +1,5 @@ +var o = {}; +gczeal(14); +for (var i = 0; i < 200; i++) { + with (o) { } +} diff --git a/js/src/jit-test/tests/gc/bug-1136597.js b/js/src/jit-test/tests/gc/bug-1136597.js new file mode 100644 index 000000000..2a9e9d190 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1136597.js @@ -0,0 +1,24 @@ +// |jit-test| error:ReferenceError +var evalInFrame = (function (global) { + var dbgGlobal = newGlobal(); + var dbg = new dbgGlobal.Debugger(); + return function evalInFrame(upCount, code) { + dbg.addDebuggee(global); + }; +})(this); +var gTestcases = new Array(); +var gTc = gTestcases.length; +function TestCase() + gTestcases[gTc++] = this; +function checkCollation(extensionCoValue, usageValue) { + var collator = new Intl.Collator(["de-DE"]); + collator.resolvedOptions().collation; +} +checkCollation(undefined, "sort"); +checkCollation(); +for ( addpow = 0; addpow < 33; addpow++ ) { + new TestCase(); +} +evalInFrame(0, "i(true)", true); +gc(3, 'shrinking') +eval("gc(); h = g1"); diff --git a/js/src/jit-test/tests/gc/bug-1137341.js b/js/src/jit-test/tests/gc/bug-1137341.js new file mode 100644 index 000000000..ec172aee3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1137341.js @@ -0,0 +1,11 @@ +if (helperThreadCount() == 0) + quit(); + +gczeal(0); +gc(); + +schedulegc(this); +startgc(0, "shrinking"); +var g = newGlobal(); +g.offThreadCompileScript('debugger;', {}); +g.runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1138390.js b/js/src/jit-test/tests/gc/bug-1138390.js new file mode 100644 index 000000000..f0f46e2fb --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1138390.js @@ -0,0 +1,28 @@ +if (!("startgc" in this && + "offThreadCompileScript" in this && + "runOffThreadScript" in this)) +{ + quit(); +} + +if (helperThreadCount() == 0) + quit(); + +gczeal(0); +gc(); + +// Start an incremental GC that includes the atoms zone +startgc(0); +var g = newGlobal(); + +// Start an off thread compilation that will not run until GC has finished +if ("gcstate" in this) + assertEq(gcstate(), "Mark"); +g.offThreadCompileScript('23;', {}); + +// Wait for the compilation to finish, which must finish the GC first +assertEq(23, g.runOffThreadScript()); +if ("gcstate" in this) + assertEq(gcstate(), "NotActive"); + +print("done"); diff --git a/js/src/jit-test/tests/gc/bug-1143706.js b/js/src/jit-test/tests/gc/bug-1143706.js new file mode 100644 index 000000000..2ae7930cb --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1143706.js @@ -0,0 +1,2 @@ +gczeal(14, 1); +var g = newGlobal(); diff --git a/js/src/jit-test/tests/gc/bug-1144738.js b/js/src/jit-test/tests/gc/bug-1144738.js new file mode 100644 index 000000000..ef121faaf --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1144738.js @@ -0,0 +1,32 @@ +// |jit-test| error: ReferenceError; --fuzzing-safe; --thread-count=1; --ion-eager +const ALL_TESTS = [ + "CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE_IS_FUNCTION", + ]; +function r(keyword, tests) { + function Reserved(keyword, tests) { + this.keyword = keyword; + if (tests) + this.tests = tests; + else + this.tests = ALL_TESTS; + } + return new Reserved(keyword, tests); +} +for (var i = 2; i >= 0; i--) { + gc(); + gczeal(14, 17); + [ + r("break"), + r("case"), + r("catch"), + r("continue"), + ]; + [ + r("true"), + r("null"), + r("each"), + r("let") + ]; +} +Failure; + diff --git a/js/src/jit-test/tests/gc/bug-1146696.js b/js/src/jit-test/tests/gc/bug-1146696.js new file mode 100644 index 000000000..070a8512c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1146696.js @@ -0,0 +1,21 @@ +// |jit-test| --no-ggc; allow-oom +gc(); +dbg1 = new Debugger(); +root2 = newGlobal(); +dbg1.memory.onGarbageCollection = function(){} +dbg1.addDebuggee(root2); +for (var j = 0; j < 9999; ++j) { + try { + a + } catch (e) {} +} +gcparam("maxBytes", gcparam("gcBytes") + 8000); +function g(i) { + if (i == 0) + return; + var x = ""; + function f() {} + eval(''); + g(i - 1); +} +g(100); diff --git a/js/src/jit-test/tests/gc/bug-1148383.js b/js/src/jit-test/tests/gc/bug-1148383.js new file mode 100644 index 000000000..5f51abbe1 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1148383.js @@ -0,0 +1,19 @@ +// This testcase tests setting object metadata for objects created from JIT +// code. +if (!("getJitCompilerOptions" in this)) + quit(); +opts = getJitCompilerOptions(); +if (!opts['ion.enable'] || !opts['baseline.enable']) + quit(); + +function TestCase() {} +function reportCompare () { + var output = ""; + var testcase = new TestCase(); + testcase.reason = output; +} +reportCompare(); +gczeal(4, 1000); +enableShellAllocationMetadataBuilder(); +for (var i = 0; i < 10000; ++i) + reportCompare(); diff --git a/js/src/jit-test/tests/gc/bug-1155455.js b/js/src/jit-test/tests/gc/bug-1155455.js new file mode 100644 index 000000000..6516d2105 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1155455.js @@ -0,0 +1,17 @@ +// |jit-test| error: TypeError +if (!("gczeal" in this)) + quit(); +var g = newGlobal(); +gczeal(10, 2) +var dbg = Debugger(g); +dbg.onDebuggerStatement = function (frame1) { + function hit(frame2) + hit[0] = "mutated"; + var s = frame1.script; + var offs = s.getLineOffsets(g.line0 + 2); + for (var i = 0; i < offs.length; i++) + s.setBreakpoint(offs[i], {hit: hit}); + return; +}; +var lfGlobal = newGlobal(); +g.eval("var line0 = Error().lineNumber;\n debugger;\nx = 1;\n"); diff --git a/js/src/jit-test/tests/gc/bug-1157577.js b/js/src/jit-test/tests/gc/bug-1157577.js new file mode 100644 index 000000000..2ec7556ea --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1157577.js @@ -0,0 +1,4 @@ +x = evalcx(''); +gcslice(10); +for (var p in x) {} + diff --git a/js/src/jit-test/tests/gc/bug-1161303.js b/js/src/jit-test/tests/gc/bug-1161303.js new file mode 100644 index 000000000..872f13763 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1161303.js @@ -0,0 +1,7 @@ +function f(x) { + for (var i = 0; i < 100000; i++ ) { + [(x, 2)]; + try { g(); } catch (t) {} + } +} +f(2); diff --git a/js/src/jit-test/tests/gc/bug-1161968.js b/js/src/jit-test/tests/gc/bug-1161968.js new file mode 100644 index 000000000..719d31424 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1161968.js @@ -0,0 +1,15 @@ +// This test case is a simplified version of debug/Source-invisible.js. + +if (!'gczeal' in this) + quit(); + +gczeal(2,21); + +var gi = newGlobal(); +gi.eval('function f() {}'); + +var gv = newGlobal(); +gv.f = gi.f; +gv.eval('f = clone(f);'); + +var dbg = new Debugger; diff --git a/js/src/jit-test/tests/gc/bug-1165966.js b/js/src/jit-test/tests/gc/bug-1165966.js new file mode 100644 index 000000000..bbcf4545e --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1165966.js @@ -0,0 +1,8 @@ +// |jit-test| --no-ion +if (!('oomTest' in this)) + quit(); + +var g = newGlobal(); +oomTest(function() { + Debugger(g); +}); diff --git a/js/src/jit-test/tests/gc/bug-1171909.js b/js/src/jit-test/tests/gc/bug-1171909.js new file mode 100644 index 000000000..16d4ff1bd --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1171909.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest((function(x) { assertEq(x + y + ex, 25); })); diff --git a/js/src/jit-test/tests/gc/bug-1175755.js b/js/src/jit-test/tests/gc/bug-1175755.js new file mode 100644 index 000000000..e0a319ce5 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1175755.js @@ -0,0 +1,9 @@ +// |jit-test| allow-oom; allow-unhandlable-oom + +if (!('oomAfterAllocations' in this)) + quit(); + +setGCCallback({ + action: "majorGC", +}); +oomAfterAllocations(50); diff --git a/js/src/jit-test/tests/gc/bug-1177778.js b/js/src/jit-test/tests/gc/bug-1177778.js new file mode 100644 index 000000000..4e70856c0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1177778.js @@ -0,0 +1,16 @@ +if (!("setGCCallback" in this)) + quit(); + +setGCCallback({ + action: "majorGC", + phases: "both" +}); +var g = newGlobal(); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); +g.eval("function h() { debugger; }"); +dbg.onDebuggerStatement = function(hframe) { + var env = hframe.older.environment; +}; +g.eval("h();"); + diff --git a/js/src/jit-test/tests/gc/bug-1188290.js b/js/src/jit-test/tests/gc/bug-1188290.js new file mode 100644 index 000000000..446ddbadc --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1188290.js @@ -0,0 +1,21 @@ +load(libdir + "immutable-prototype.js"); + +if (globalPrototypeChainIsMutable()) + this.__proto__ = []; + +if (!this.hasOwnProperty("TypedObject") || typeof minorgc !== 'function') + quit(); + +var T = TypedObject; +var ObjectStruct = new T.StructType({f: T.Object}); +var o = new ObjectStruct(); + +minorgc(); + +function writeObject(o, v) { + o.f = v; + assertEq(typeof o.f, "object"); +} + +for (var i = 0; i < 5; i++) + writeObject(o, { toString: function() { return "helo"; } }); diff --git a/js/src/jit-test/tests/gc/bug-1191576.js b/js/src/jit-test/tests/gc/bug-1191576.js new file mode 100644 index 000000000..6a3369cc4 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1191576.js @@ -0,0 +1,17 @@ +// |jit-test| allow-oom + +if (!('gczeal' in this && 'oomAfterAllocations' in this)) + quit(); + +var lfcode = new Array(); +gczeal(14); +loadFile(` +for each(let e in newGlobal()) { + if (oomAfterAllocations(100)) + continue; +} +`); +function loadFile(lfVarx) { + for (lfLocal in this) {} + evaluate(lfVarx); +} diff --git a/js/src/jit-test/tests/gc/bug-1196210.js b/js/src/jit-test/tests/gc/bug-1196210.js new file mode 100644 index 000000000..dbdf4fe81 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1196210.js @@ -0,0 +1,14 @@ +function foo() { + function testGeneratorDeepBail() { + gc(); + for (let i = 0; Error(); i++) { + for each(var x in [{n: 1}, {n: 1}]) { + x[0] = 0; + Object.freeze(x); + } + if (i == 10) + break; + } + } + testGeneratorDeepBail(); +} foo(); diff --git a/js/src/jit-test/tests/gc/bug-1206677.js b/js/src/jit-test/tests/gc/bug-1206677.js new file mode 100644 index 000000000..c666b7aac --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1206677.js @@ -0,0 +1,12 @@ +if (!('oomTest' in this) || helperThreadCount() === 0) + quit(0); + +var lfGlobal = newGlobal(); +for (lfLocal in this) { + if (!(lfLocal in lfGlobal)) { + lfGlobal[lfLocal] = this[lfLocal]; + } +} +const script = 'oomTest(() => getBacktrace({args: true, locals: "123795", thisprops: true}));'; +lfGlobal.offThreadCompileScript(script); +lfGlobal.runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1208994.js b/js/src/jit-test/tests/gc/bug-1208994.js new file mode 100644 index 000000000..b2326cd62 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1208994.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => getBacktrace({args: oomTest[load+1], locals: true, thisprops: true})); diff --git a/js/src/jit-test/tests/gc/bug-1209001.js b/js/src/jit-test/tests/gc/bug-1209001.js new file mode 100644 index 000000000..dfbf54b31 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1209001.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => parseModule('import v from "mod";')); diff --git a/js/src/jit-test/tests/gc/bug-1210607.js b/js/src/jit-test/tests/gc/bug-1210607.js new file mode 100644 index 000000000..fefbd95f4 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1210607.js @@ -0,0 +1,9 @@ +// |jit-test| allow-oom + +if (!('oomAfterAllocations' in this)) + quit(); + +var g = newGlobal(); +x = Debugger(g); +selectforgc(g); +oomAfterAllocations(1); diff --git a/js/src/jit-test/tests/gc/bug-1214006.js b/js/src/jit-test/tests/gc/bug-1214006.js new file mode 100644 index 000000000..5b069e686 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1214006.js @@ -0,0 +1,10 @@ +// |jit-test| allow-oom + +if (!('oomTest' in this)) + quit(); + +function f() { + eval("(function() y)()"); +} +oomTest(f); +fullcompartmentchecks(true); diff --git a/js/src/jit-test/tests/gc/bug-1214781.js b/js/src/jit-test/tests/gc/bug-1214781.js new file mode 100644 index 000000000..d74a55c2b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1214781.js @@ -0,0 +1,8 @@ +if (!('oomTest' in this)) + quit(); + +try { + gcparam("maxBytes", gcparam("gcBytes")); + newGlobal(""); +} catch (e) {}; +oomTest(function() {}) diff --git a/js/src/jit-test/tests/gc/bug-1214846.js b/js/src/jit-test/tests/gc/bug-1214846.js new file mode 100644 index 000000000..f147d1807 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1214846.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this) || helperThreadCount() === 0) + quit(); + +enableSPSProfiling(); +var s = newGlobal(); +s.offThreadCompileScript('oomTest(() => {});'); +s.runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1215363-1.js b/js/src/jit-test/tests/gc/bug-1215363-1.js new file mode 100644 index 000000000..d3a2bae65 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1215363-1.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => parseModule(10)); diff --git a/js/src/jit-test/tests/gc/bug-1215363-2.js b/js/src/jit-test/tests/gc/bug-1215363-2.js new file mode 100644 index 000000000..92c6c64d0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1215363-2.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); + +var lfcode = new Array(); +oomTest((function(x) { + assertEq(...Object); +})); diff --git a/js/src/jit-test/tests/gc/bug-1215363-3.js b/js/src/jit-test/tests/gc/bug-1215363-3.js new file mode 100644 index 000000000..558e1c0f3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1215363-3.js @@ -0,0 +1,5 @@ +if (!('oomTest' in this)) + quit(); + +var lfcode = new Array(); +oomTest(() => getBacktrace({})); diff --git a/js/src/jit-test/tests/gc/bug-1215678.js b/js/src/jit-test/tests/gc/bug-1215678.js new file mode 100644 index 000000000..8a9723776 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1215678.js @@ -0,0 +1,10 @@ +// |jit-test| error: ReferenceError +if (!('oomTest' in this)) + a; + +enableShellAllocationMetadataBuilder() +oomTest(() => { + newGlobal() +}) +gczeal(9, 1); +a; diff --git a/js/src/jit-test/tests/gc/bug-1216607.js b/js/src/jit-test/tests/gc/bug-1216607.js new file mode 100644 index 000000000..5187a47b8 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1216607.js @@ -0,0 +1,19 @@ +if (!('oomTest' in this)) + quit(); + +enableSPSProfilingWithSlowAssertions(); +try { +(function() { + while (n--) { + } +})(); +} catch(exc1) {} +function arrayProtoOutOfRange() { + function f(obj) {} + function test() { + for (var i = 0; i < 1000; i++) + var r = f(i % 2 ? a : b); + } + test(); +} +oomTest(arrayProtoOutOfRange); diff --git a/js/src/jit-test/tests/gc/bug-1218900-2.js b/js/src/jit-test/tests/gc/bug-1218900-2.js new file mode 100644 index 000000000..6e9947526 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1218900-2.js @@ -0,0 +1,3 @@ +// |jit-test| error: Error +startTimingMutator(); +startTimingMutator(); diff --git a/js/src/jit-test/tests/gc/bug-1218900.js b/js/src/jit-test/tests/gc/bug-1218900.js new file mode 100644 index 000000000..a3bc82bd2 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1218900.js @@ -0,0 +1,8 @@ +// |jit-test| --fuzzing-safe +readline = function() {}; +Function.prototype.toString = function() { + for (var i = 0; i < 2; i++) { + this() + } +}; +getBacktrace({thisprops: true}); diff --git a/js/src/jit-test/tests/gc/bug-1221359.js b/js/src/jit-test/tests/gc/bug-1221359.js new file mode 100644 index 000000000..806ae315c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1221359.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => getBacktrace({ + locals: true, + thisprops: true +})); diff --git a/js/src/jit-test/tests/gc/bug-1221747.js b/js/src/jit-test/tests/gc/bug-1221747.js new file mode 100644 index 000000000..fca794fc6 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1221747.js @@ -0,0 +1,8 @@ +// |jit-test| --dump-bytecode +if (!('oomTest' in this)) + quit(); + +function f() { + eval("(function() {})()"); +} +oomTest(f); diff --git a/js/src/jit-test/tests/gc/bug-1223021.js b/js/src/jit-test/tests/gc/bug-1223021.js new file mode 100644 index 000000000..702da52d9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1223021.js @@ -0,0 +1,12 @@ +if (!('oomTest' in this)) + quit(); + +function f() { + return this === null; +}; + +function g() { + if (!f.apply(9)) {} +} + +oomTest(g); diff --git a/js/src/jit-test/tests/gc/bug-1224710.js b/js/src/jit-test/tests/gc/bug-1224710.js new file mode 100644 index 000000000..f772b6a54 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1224710.js @@ -0,0 +1,14 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(function() { + eval("\ + function g() {\ + \"use asm\";\ + function f(d) {\ + d = +d;\ + print(.0 + d);\ + }\ + }\ + ") +}) diff --git a/js/src/jit-test/tests/gc/bug-1226888.js b/js/src/jit-test/tests/gc/bug-1226888.js new file mode 100644 index 000000000..9ae6b4a50 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1226888.js @@ -0,0 +1,19 @@ +if (!this.hasOwnProperty("TypedObject")) + quit(); + +setJitCompilerOption('ion.forceinlineCaches', 1); +// Adapted from randomly chosen test: js/src/jit-test/tests/TypedObject/jit-write-references.js +with({}) {} +v = new new TypedObject.StructType({ + f: TypedObject.Any +}) +gc(); +function g() { + v.f = { + Object + }; + v.f; +} +for (var i = 0; i < 9; i++) { + g(); +} diff --git a/js/src/jit-test/tests/gc/bug-1226896.js b/js/src/jit-test/tests/gc/bug-1226896.js new file mode 100644 index 000000000..0af52f2ce --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1226896.js @@ -0,0 +1,9 @@ +// |jit-test| --ion-pgo=on + +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + var g = newGlobal(); + g.eval("(function() {})()"); +}); diff --git a/js/src/jit-test/tests/gc/bug-1231386.js b/js/src/jit-test/tests/gc/bug-1231386.js new file mode 100644 index 000000000..35cfc7a91 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1231386.js @@ -0,0 +1,19 @@ +if (!('oomTest' in this)) + quit(); + +function f1() {} +function f2() {} +r = [function() {}, function() {}, [], function() {}, f1, function() {}, f2]; +l = [0]; +function f3() { + return { + a: 0 + }; +} +var x = f3(); +var h = newGlobal(); +var dbg = new Debugger; +dbg.addDebuggee(h); +oomTest(() => getBacktrace({ + thisprops: gc() +})); diff --git a/js/src/jit-test/tests/gc/bug-1232386.js b/js/src/jit-test/tests/gc/bug-1232386.js new file mode 100644 index 000000000..32f6dab3f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1232386.js @@ -0,0 +1,12 @@ +// |jit-test| allow-oom +if (!('oomTest' in this)) + quit(); + +var dbg = new Debugger; +dbg.onNewGlobalObject = function(global) { + global.seen = true; +}; + +oomTest(function() { + newGlobal({sameZoneAs: this}) +}); diff --git a/js/src/jit-test/tests/gc/bug-1234410.js b/js/src/jit-test/tests/gc/bug-1234410.js new file mode 100644 index 000000000..11ae164f4 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1234410.js @@ -0,0 +1,10 @@ +if (!('oomTest' in this)) + quit(); + +enableSPSProfiling(); +oomTest(() => { + try { + for (var quit of oomTest.gcparam("//").ArrayBuffer(1)) {} + } catch (e) {} +}); + diff --git a/js/src/jit-test/tests/gc/bug-1236473.js b/js/src/jit-test/tests/gc/bug-1236473.js new file mode 100644 index 000000000..e48edd393 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1236473.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + offThreadCompileScript(`try {} catch (NaN) {}`); + runOffThreadScript(); +}); diff --git a/js/src/jit-test/tests/gc/bug-1237153.js b/js/src/jit-test/tests/gc/bug-1237153.js new file mode 100644 index 000000000..4b3f04b1f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1237153.js @@ -0,0 +1,2 @@ +// |jit-test| error: Error +gcparam("sliceTimeBudget", -1); diff --git a/js/src/jit-test/tests/gc/bug-1238548.js b/js/src/jit-test/tests/gc/bug-1238548.js new file mode 100644 index 000000000..9424ffb9c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1238548.js @@ -0,0 +1,2 @@ +// |jit-test| error: Error +gcparam("highFrequencyHeapGrowthMax", 1); diff --git a/js/src/jit-test/tests/gc/bug-1238555.js b/js/src/jit-test/tests/gc/bug-1238555.js new file mode 100644 index 000000000..8d72ecfdc --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1238555.js @@ -0,0 +1,12 @@ +if (!('oomTest' in this)) + quit(); + +oomTest( + function x() { + try { + eval('let ') + } catch (ex) { + (function() {})() + } + } +); diff --git a/js/src/jit-test/tests/gc/bug-1238575-2.js b/js/src/jit-test/tests/gc/bug-1238575-2.js new file mode 100644 index 000000000..73739b795 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1238575-2.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => evalInWorker("1")); diff --git a/js/src/jit-test/tests/gc/bug-1238575.js b/js/src/jit-test/tests/gc/bug-1238575.js new file mode 100644 index 000000000..248509364 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1238575.js @@ -0,0 +1,8 @@ +// |jit-test| allow-oom; allow-unhandlable-oom + +if (!('oomAfterAllocations' in this)) + quit(); + +oomAfterAllocations(5) +gcslice(11); +evalInWorker("1"); diff --git a/js/src/jit-test/tests/gc/bug-1238582.js b/js/src/jit-test/tests/gc/bug-1238582.js new file mode 100644 index 000000000..60286c8ee --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1238582.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => { let a = [2147483651]; [a[0], a[undefined]].sort(); }); diff --git a/js/src/jit-test/tests/gc/bug-1240416.js b/js/src/jit-test/tests/gc/bug-1240416.js new file mode 100644 index 000000000..e3a1bab82 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1240416.js @@ -0,0 +1,2 @@ +// |jit-test| error: Error +gcparam('markStackLimit', 0); diff --git a/js/src/jit-test/tests/gc/bug-1240503.js b/js/src/jit-test/tests/gc/bug-1240503.js new file mode 100644 index 000000000..0cc7cabe0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1240503.js @@ -0,0 +1,8 @@ +if (!('oomTest' in this)) + quit(); + +function arrayProtoOutOfRange() { + for (let [] = () => r, get;;) + var r = f(i % 2 ? a : b); +} +oomTest(arrayProtoOutOfRange); diff --git a/js/src/jit-test/tests/gc/bug-1240527.js b/js/src/jit-test/tests/gc/bug-1240527.js new file mode 100644 index 000000000..7bdccf018 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1240527.js @@ -0,0 +1,14 @@ +if (typeof offThreadCompileScript !== 'function' || + typeof runOffThreadScript !== 'function' || + typeof oomTest !== 'function' || + typeof fullcompartmentchecks !== 'function' || + helperThreadCount() === 0) +{ + quit(0); +} + +offThreadCompileScript(` + oomTest(() => "".search(/d/)); + fullcompartmentchecks(3); +`); +runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1241731.js b/js/src/jit-test/tests/gc/bug-1241731.js new file mode 100644 index 000000000..2264c89eb --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1241731.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => serialize(0, [{}])); diff --git a/js/src/jit-test/tests/gc/bug-1242812.js b/js/src/jit-test/tests/gc/bug-1242812.js new file mode 100644 index 000000000..61253bec1 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1242812.js @@ -0,0 +1,5 @@ +if (!('oomTest' in this)) + quit(); + +var lfcode = new Array(); +oomTest(() => { let a = [2147483651]; [-1, 0, 1, 31, 32].sort(); }); diff --git a/js/src/jit-test/tests/gc/bug-1245520.js b/js/src/jit-test/tests/gc/bug-1245520.js new file mode 100644 index 000000000..1e018371a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1245520.js @@ -0,0 +1,5 @@ +if (!('oomTest' in this)) + quit(); + +var t = {}; +oomTest(() => serialize(t)); diff --git a/js/src/jit-test/tests/gc/bug-1246593.js b/js/src/jit-test/tests/gc/bug-1246593.js new file mode 100644 index 000000000..4d90bbb24 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1246593.js @@ -0,0 +1,4 @@ +length = 10000; +array = Array(); +for (i = length;i > -100000; i--) + array[i] = {}; diff --git a/js/src/jit-test/tests/gc/bug-1252103.js b/js/src/jit-test/tests/gc/bug-1252103.js new file mode 100644 index 000000000..7c2bc361b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1252103.js @@ -0,0 +1,22 @@ +// Bug 1252103: Inline typed array objects need delayed metadata collection. +// Shouldn't crash. + +if (!this.hasOwnProperty("TypedObject")) + quit(); + +function foo() { + enableTrackAllocations(); + gczeal(2, 10); + TO = TypedObject; + PointType = new TO.StructType({ + y: TO.float64, + name: TO.string + }) + LineType = new TO.StructType({ + PointType + }) + function testBasic() new LineType; + testBasic(); +} +evaluate("foo()"); + diff --git a/js/src/jit-test/tests/gc/bug-1252154.js b/js/src/jit-test/tests/gc/bug-1252154.js new file mode 100644 index 000000000..192395696 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1252154.js @@ -0,0 +1,11 @@ +// Bug 1252154: Inline typed array objects need delayed metadata collection. +// Shouldn't crash. + +if (!this.hasOwnProperty("TypedObject")) + quit(); + +gczeal(7,1); +enableShellAllocationMetadataBuilder(); +var T = TypedObject; +var AT = new T.ArrayType(T.Any,10); +var v = new AT(); diff --git a/js/src/jit-test/tests/gc/bug-1252329.js b/js/src/jit-test/tests/gc/bug-1252329.js new file mode 100644 index 000000000..172f3fbc7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1252329.js @@ -0,0 +1,34 @@ +// |jit-test| allow-oom + +if (helperThreadCount() == 0 || !('oomAfterAllocations' in this)) + quit(); + +var lfcode = new Array(); +lfcode.push("5"); +lfcode.push(` +gczeal(8, 2); +try { + [new String, y] +} catch (e) {} +oomAfterAllocations(50); +try { + (5).replace(r, () => {}); +} catch (x) {} +`); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + switch (lfRunTypeId) { + case 5: + var lfGlobal = newGlobal(); + for (lfLocal in this) {} + lfGlobal.offThreadCompileScript(lfVarx); + lfGlobal.runOffThreadScript(); + } + } else if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } +} diff --git a/js/src/jit-test/tests/gc/bug-1253124.js b/js/src/jit-test/tests/gc/bug-1253124.js new file mode 100644 index 000000000..730b2419a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1253124.js @@ -0,0 +1,11 @@ +if (!('oomTest' in this)) + quit(); + +for (let i = 0; i < 10; i++) + toPrimitive = Date.prototype[Symbol.toPrimitive]; +assertThrowsInstanceOf(() => 0); +obj = {}; +oomTest(() => assertThrowsInstanceOf(() => toPrimitive.call(obj, "boolean"))); +function assertThrowsInstanceOf(f) { + f(); +} diff --git a/js/src/jit-test/tests/gc/bug-1254108.js b/js/src/jit-test/tests/gc/bug-1254108.js new file mode 100644 index 000000000..bf18e798a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1254108.js @@ -0,0 +1,5 @@ +|jit-test| error: Error +function testChangeParam(key) { + gcparam(key, 0x22222222); +} +testChangeParam("lowFrequencyHeapGrowth"); diff --git a/js/src/jit-test/tests/gc/bug-1258407.js b/js/src/jit-test/tests/gc/bug-1258407.js new file mode 100644 index 000000000..9338c981f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1258407.js @@ -0,0 +1,10 @@ +|jit-test| error: Error +gcparam("lowFrequencyHeapGrowth", 0.1); +gcparam("lowFrequencyHeapGrowth", 2); +let ok = false; +try { + gcparam("lowFrequencyHeapGrowth", 0x22222222); +} catch (e) { + ok = true; +} +assertEq(ok, true); diff --git a/js/src/jit-test/tests/gc/bug-1259306.js b/js/src/jit-test/tests/gc/bug-1259306.js new file mode 100644 index 000000000..4f8412dad --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1259306.js @@ -0,0 +1,19 @@ +if (!('oomTest' in this)) + quit(); + +let runCount = 0; +oomTest(() => { + if (runCount < 5) { + let lfGlobal = newGlobal(); + var lfVarx = ` + gczeal(8, 1); + try { + (5).replace(r, () => {}); + } catch (x) {} + gczeal(0); + `; + lfGlobal.offThreadCompileScript(lfVarx); + lfGlobal.runOffThreadScript(); + runCount++; + } +}); diff --git a/js/src/jit-test/tests/gc/bug-1259490.js b/js/src/jit-test/tests/gc/bug-1259490.js new file mode 100644 index 000000000..063b4236e --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1259490.js @@ -0,0 +1,9 @@ +try { eval("3 ** 4") } catch (e if e instanceof SyntaxError) { quit(); }; +eval(` + +gczeal(8); +for (var k = 0; k < 99; ++k) { + uneval(-(0 ** (Object | 0 * Object))) +} + +`) diff --git a/js/src/jit-test/tests/gc/bug-1261329.js b/js/src/jit-test/tests/gc/bug-1261329.js new file mode 100644 index 000000000..6a4a30761 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1261329.js @@ -0,0 +1,10 @@ +if (!('oomTest' in this)) + quit(); + +print = function() {} +function k() dissrc(print); +function j() k(); +function h() j(); +function f() h(); +f(); +oomTest(() => f()) diff --git a/js/src/jit-test/tests/gc/bug-1263862.js b/js/src/jit-test/tests/gc/bug-1263862.js new file mode 100644 index 000000000..04bc61009 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1263862.js @@ -0,0 +1,9 @@ +if (!('oomTest' in this)) + quit(); + +function loadFile(lfVarx) { + oomTest(() => eval(lfVarx)); +} +for (var i = 0; i < 10; ++i) { + loadFile(`"use strict"; const s = () => s;`); +} diff --git a/js/src/jit-test/tests/gc/bug-1263871.js b/js/src/jit-test/tests/gc/bug-1263871.js new file mode 100644 index 000000000..96bbf50b9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1263871.js @@ -0,0 +1,8 @@ +if (!('oomTest' in this)) + quit(); + +lfLogBuffer = `this[''] = function() {}`; +loadFile(lfLogBuffer); +loadFile(lfLogBuffer); +function loadFile(lfVarx) + oomTest(function() parseModule(lfVarx)) diff --git a/js/src/jit-test/tests/gc/bug-1263884.js b/js/src/jit-test/tests/gc/bug-1263884.js new file mode 100644 index 000000000..50c352756 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1263884.js @@ -0,0 +1,10 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(function() { + eval(` + var argObj = function () { return arguments }() + for (var p in argObj); + delete argObj.callee; + `); +}); diff --git a/js/src/jit-test/tests/gc/bug-1271110.js b/js/src/jit-test/tests/gc/bug-1271110.js new file mode 100644 index 000000000..b3b68a277 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1271110.js @@ -0,0 +1,37 @@ +if (!('oomTest' in this)) + quit(); + +var x1 = []; +var x2 = []; +var x3 = []; +var x4 = []; +(function() { + var gns = Object.getOwnPropertyNames(this); + for (var i = 0; i < 49; ++i) { + var gn = gns[i]; + var g = this[gn]; + if (typeof g == "function") { + var hns = Object.getOwnPropertyNames(gn); + for (var j = 0; j < hns.length; ++j) { + x1.push(""); + x1.push(""); + x2.push(""); + x2.push(""); + x3.push(""); + x3.push(""); + x4.push(""); + x4.push(""); + } + } + } +})(); +try { + __proto__ = function(){}; +} catch (e) { + "" + e; +} +startgc(9222); +Function("\ + (function() {})();\ + oomTest(Debugger.Script);\ +")(); diff --git a/js/src/jit-test/tests/gc/bug-1276631.js b/js/src/jit-test/tests/gc/bug-1276631.js new file mode 100644 index 000000000..f80e7f021 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1276631.js @@ -0,0 +1,17 @@ +gczeal(15,5); +try { + foobar(); +} catch (e) {} +function newFunc(x) { + new Function(x)(); +}; +loadFile(` + try { gczeal(10, 2)() } catch (e) {} +`); +function loadFile(lfVarx) { + function newFunc(x) { + new Function(x)(); + }; + newFunc(lfVarx); + if (helperThreadCount() && getJitCompilerOptions()["offthread-compilation.enable"]) {} +} diff --git a/js/src/jit-test/tests/gc/bug-1278832.js b/js/src/jit-test/tests/gc/bug-1278832.js new file mode 100644 index 000000000..aa9e269b3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1278832.js @@ -0,0 +1,12 @@ +function assertThrowsInstanceOf() {} +gczeal(15) +try { + gczeal(10, 2) +} catch (Atomics) {} +for (define of[__defineSetter__]) { + let nonCallable = [{}] + for (let value of nonCallable) assertThrowsInstanceOf(TypeError) + key = { + [Symbol]() {} + } +} diff --git a/js/src/jit-test/tests/gc/bug-1280588.js b/js/src/jit-test/tests/gc/bug-1280588.js new file mode 100644 index 000000000..c12aed2c2 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1280588.js @@ -0,0 +1,6 @@ +if (!('oomTest' in this)) + quit(); + +var x = []; +oomTest(() => setGCCallback({ action: "minorGC" })); +oomTest(() => setGCCallback({ action: "majorGC" })); diff --git a/js/src/jit-test/tests/gc/bug-1280889.js b/js/src/jit-test/tests/gc/bug-1280889.js new file mode 100644 index 000000000..a0ff520a7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1280889.js @@ -0,0 +1,9 @@ +if (helperThreadCount() == 0) + quit(); + +evalInWorker(` + function f() { + fullcompartmentchecks(f); + } + try { f(); } catch(e) {} +`); diff --git a/js/src/jit-test/tests/gc/bug-1282986.js b/js/src/jit-test/tests/gc/bug-1282986.js new file mode 100644 index 000000000..5c2c3ab67 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1282986.js @@ -0,0 +1,17 @@ +if (!('oomTest' in this)) + quit(); + +var lfLogBuffer = ` +evalInWorker(\` + try { oomAfterAllocations(2); } catch(e) {} + \`); +`; +loadFile(""); +loadFile(lfLogBuffer); +function loadFile(lfVarx) { + oomTest(function() { + let m = parseModule(lfVarx); + m.declarationInstantiation(); + m.evaluation(); + }); +} diff --git a/js/src/jit-test/tests/gc/bug-1286244.js b/js/src/jit-test/tests/gc/bug-1286244.js new file mode 100644 index 000000000..c489f95c2 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1286244.js @@ -0,0 +1,16 @@ +if (typeof verifyprebarriers != 'function' || + typeof offThreadCompileScript != 'function') + quit(); + +try { + // This will fail with --no-threads. + verifyprebarriers(); + var lfGlobal = newGlobal(); + lfGlobal.offThreadCompileScript(` + version(185); + `); +} +catch (e) { + quit(0); +} + diff --git a/js/src/jit-test/tests/gc/bug-1287399.js b/js/src/jit-test/tests/gc/bug-1287399.js new file mode 100644 index 000000000..edaf0901b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1287399.js @@ -0,0 +1,12 @@ +if (typeof gczeal != "function" || helperThreadCount() === 0) + quit(0); + +var lfGlobal = newGlobal(); +gczeal(4); +for (lfLocal in this) {} +lfGlobal.offThreadCompileScript(` + var desc = { + value: 'bar', + value: false, + }; +`); diff --git a/js/src/jit-test/tests/gc/bug-1287869.js b/js/src/jit-test/tests/gc/bug-1287869.js new file mode 100644 index 000000000..7c1e8662e --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1287869.js @@ -0,0 +1,8 @@ +if (!('gczeal' in this)) + quit(); + +gczeal(16); +let a = []; +for (let i = 0; i < 1000; i++) + a.push({x: i}); +gc(); diff --git a/js/src/jit-test/tests/gc/bug-1292564.js b/js/src/jit-test/tests/gc/bug-1292564.js new file mode 100644 index 000000000..5c072b475 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1292564.js @@ -0,0 +1,12 @@ +// |jit-test| allow-oom + +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + let global = newGlobal(); + Debugger(global).onDebuggerStatement = function (frame) { + frame.eval("f") + } + global.eval("debugger") +}, false); diff --git a/js/src/jit-test/tests/gc/bug-1293127.js b/js/src/jit-test/tests/gc/bug-1293127.js new file mode 100644 index 000000000..1e4999e91 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1293127.js @@ -0,0 +1,11 @@ +// Test that we can create 1000 cross compartment wrappers to nursery objects +// without trigger a minor GC. +gczeal(0); +let g = newGlobal(); +evalcx("function f(x) { return {x: x}; }", g); +gc(); +let initial = gcparam("gcNumber"); +for (let i = 0; i < 1000; i++) + g.f(i); +let final = gcparam("gcNumber"); +assertEq(final, initial); diff --git a/js/src/jit-test/tests/gc/bug-1294241.js b/js/src/jit-test/tests/gc/bug-1294241.js new file mode 100644 index 000000000..d993830e7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1294241.js @@ -0,0 +1,10 @@ +if (helperThreadCount() == 0) + quit(); + +gczeal(9); +function rejectionTracker(state) {} +setPromiseRejectionTrackerCallback(rejectionTracker) + lfGlobal = newGlobal(); +offThreadCompileScript(`new Promise(()=>rej)`); +lfGlobal.runOffThreadScript(); +for (lfLocal in this); diff --git a/js/src/jit-test/tests/gc/bug-1298356.js b/js/src/jit-test/tests/gc/bug-1298356.js new file mode 100644 index 000000000..ced15ec61 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1298356.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); + +/x/; +oomTest(function(){ + offThreadCompileScript(''); +}) diff --git a/js/src/jit-test/tests/gc/bug-1301377.js b/js/src/jit-test/tests/gc/bug-1301377.js new file mode 100644 index 000000000..1e6f475ad --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1301377.js @@ -0,0 +1,12 @@ +var lfLogBuffer = ` + gczeal(14); + enableSPSProfiling(); + gczeal(15,3); + var s = ""; + for (let i = 0; i != 30; i+=2) {} + readSPSProfilingStack(s, "c0d1c0d1c0d1c0d1c0d1c0d1c0d1c0"); +`; +loadFile(lfLogBuffer); +function loadFile(lfVarx) { + evaluate(lfVarx); +} diff --git a/js/src/jit-test/tests/gc/bug-1301496.js b/js/src/jit-test/tests/gc/bug-1301496.js new file mode 100644 index 000000000..7200ab98c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1301496.js @@ -0,0 +1,7 @@ +if (helperThreadCount() == 0) + quit(); +startgc(1, 'shrinking'); +offThreadCompileScript(""); +// Adapted from randomly chosen test: js/src/jit-test/tests/parser/bug-1263355-13.js +gczeal(9); +newGlobal(); diff --git a/js/src/jit-test/tests/gc/bug-1303015.js b/js/src/jit-test/tests/gc/bug-1303015.js new file mode 100644 index 000000000..70d9f2102 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1303015.js @@ -0,0 +1,13 @@ +if (!('oomTest' in this)) + quit(); + +var x = ``.split(); +oomTest(function() { + var lfGlobal = newGlobal(); + for (lfLocal in this) { + if (!(lfLocal in lfGlobal)) { + lfGlobal[lfLocal] = this[lfLocal]; + } + } +}); + diff --git a/js/src/jit-test/tests/gc/bug-1305220.js b/js/src/jit-test/tests/gc/bug-1305220.js new file mode 100644 index 000000000..30d3fa260 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1305220.js @@ -0,0 +1,23 @@ +// |jit-test| allow-oom +if (!('oomAfterAllocations' in this)) + quit(); +s = newGlobal(); +evalcx("\ + gczeal(10, 2);\ + k = {\ + [Symbol]() {}\ + };\ +", s); +gczeal(0); +evalcx("\ + var g = newGlobal();\ + b = new Debugger;\ + g.h = function() {\ + g.oomAfterAllocations(1);\ + };\ + g.eval(\"\" + function f() g());\ + g.eval(\"\" + function g() h());\ + g.eval(\"(\" + function() {\ + f();\ + } + \")()\");\ +", s); diff --git a/js/src/jit-test/tests/gc/bug-1308048.js b/js/src/jit-test/tests/gc/bug-1308048.js new file mode 100644 index 000000000..8cf2fba6b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1308048.js @@ -0,0 +1,10 @@ +if (helperThreadCount() == 0) + quit(); + +m = 'x'; +for (var i = 0; i < 10; i++) + m += m; +offThreadCompileScript("", ({elementAttributeName: m})); +var n = newGlobal(); +gczeal(2,1); +n.runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1310589.js b/js/src/jit-test/tests/gc/bug-1310589.js new file mode 100644 index 000000000..672922832 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1310589.js @@ -0,0 +1,299 @@ +if (!('oomTest' in this)) + quit(); + +a = o = s = r = [] +o2 = s2 = r2 = g2 = f2 = m2 = Map +e2 = Set +v2 = b2 = new ArrayBuffer +t2 = new Uint8ClampedArray +minorgc() +x = /x/ +for (var i = 0; i < 4; ++i) { + function f1() {} +} +Object.defineProperty(a, 12, {}).push(1); +toString = (function() a.reverse()) +oomTest(Date.prototype.toJSON) +function f1000(){} +function f1001(){} +function f1002(){} +function f1003(){} +function f1004(){} +function f1005(){} +function f1006(){} +function f1007(){} +function f1008(){} +function f1009(){} +function f1010(){} +function f1011(){} +function f1012(){} +function f1013(){} +function f1014(){} +function f1015(){} +function f1016(){} +function f1017(){} +function f1018(){} +function f1019(){} +function f1020(){} +function f1021(){} +function f1022(){} +function f1023(){} +function f1024(){} +function f1025(){} +function f1026(){} +function f1027(){} +function f1028(){} +function f1029(){} +function f1030(){} +function f1031(){} +function f1032(){} +function f1033(){} +function f1034(){} +function f1035(){} +function f1036(){} +function f1037(){} +function f1038(){} +function f1039(){} +function f1040(){} +function f1041(){} +function f1042(){} +function f1043(){} +function f1044(){} +function f1045(){} +function f1046(){} +function f1047(){} +function f1048(){} +function f1049(){} +function f1050(){} +function f1051(){} +function f1052(){} +function f1053(){} +function f1054(){} +function f1055(){} +function f1056(){} +function f1057(){} +function f1058(){} +function f1059(){} +function f1060(){} +function f1061(){} +function f1062(){} +function f1063(){} +function f1064(){} +function f1065(){} +function f1066(){} +function f1067(){} +function f1068(){} +function f1069(){} +function f1070(){} +function f1071(){} +function f1072(){} +function f1073(){} +function f1074(){} +function f1075(){} +function f1076(){} +function f1077(){} +function f1078(){} +function f1079(){} +function f1080(){} +function f1081(){} +function f1082(){} +function f1083(){} +function f1084(){} +function f1085(){} +function f1086(){} +function f1087(){} +function f1088(){} +function f1089(){} +function f1090(){} +function f1091(){} +function f1092(){} +function f1093(){} +function f1094(){} +function f1095(){} +function f1096(){} +function f1097(){} +function f1098(){} +function f1099(){} +function f1100(){} +function f1101(){} +function f1102(){} +function f1103(){} +function f1104(){} +function f1105(){} +function f1106(){} +function f1107(){} +function f1108(){} +function f1109(){} +function f1110(){} +function f1111(){} +function f1112(){} +function f1113(){} +function f1114(){} +function f1115(){} +function f1116(){} +function f1117(){} +function f1118(){} +function f1119(){} +function f1120(){} +function f1121(){} +function f1122(){} +function f1123(){} +function f1124(){} +function f1125(){} +function f1126(){} +function f1127(){} +function f1128(){} +function f1129(){} +function f1130(){} +function f1131(){} +function f1132(){} +function f1133(){} +function f1134(){} +function f1135(){} +function f1136(){} +function f1137(){} +function f1138(){} +function f1139(){} +function f1140(){} +function f1141(){} +function f1142(){} +function f1143(){} +function f1144(){} +function f1145(){} +function f1146(){} +function f1147(){} +function f1148(){} +function f1149(){} +function f1150(){} +function f1151(){} +function f1152(){} +function f1153(){} +function f1154(){} +function f1155(){} +function f1156(){} +function f1157(){} +function f1158(){} +function f1159(){} +function f1160(){} +function f1161(){} +function f1162(){} +function f1163(){} +function f1164(){} +function f1165(){} +function f1166(){} +function f1167(){} +function f1168(){} +function f1169(){} +function f1170(){} +function f1171(){} +function f1172(){} +function f1173(){} +function f1174(){} +function f1175(){} +function f1176(){} +function f1177(){} +function f1178(){} +function f1179(){} +function f1180(){} +function f1181(){} +function f1182(){} +function f1183(){} +function f1184(){} +function f1185(){} +function f1186(){} +function f1187(){} +function f1188(){} +function f1189(){} +function f1190(){} +function f1191(){} +function f1192(){} +function f1193(){} +function f1194(){} +function f1195(){} +function f1196(){} +function f1197(){} +function f1198(){} +function f1199(){} +function f1200(){} +function f1201(){} +function f1202(){} +function f1203(){} +function f1204(){} +function f1205(){} +function f1206(){} +function f1207(){} +function f1208(){} +function f1209(){} +function f1210(){} +function f1211(){} +function f1212(){} +function f1213(){} +function f1214(){} +function f1215(){} +function f1216(){} +function f1217(){} +function f1218(){} +function f1219(){} +function f1220(){} +function f1221(){} +function f1222(){} +function f1223(){} +function f1224(){} +function f1225(){} +function f1226(){} +function f1227(){} +function f1228(){} +function f1229(){} +function f1230(){} +function f1231(){} +function f1232(){} +function f1233(){} +function f1234(){} +function f1235(){} +function f1236(){} +function f1237(){} +function f1238(){} +function f1239(){} +function f1240(){} +function f1241(){} +function f1242(){} +function f1243(){} +function f1244(){} +function f1245(){} +function f1246(){} +function f1247(){} +function f1248(){} +function f1249(){} +function f1250(){} +function f1251(){} +function f1252(){} +function f1253(){} +function f1254(){} +function f1255(){} +function f1256(){} +function f1257(){} +function f1258(){} +function f1259(){} +function f1260(){} +function f1261(){} +function f1262(){} +function f1263(){} +function f1264(){} +function f1265(){} +function f1266(){} +function f1267(){} +function f1268(){} +function f1269(){} +function f1270(){} +function f1271(){} +function f1272(){} +function f1273(){} +function f1274(){} +function f1275(){} +function f1276(){} +function f1277(){} +function f1278(){} +function f1279(){} +function f1280(){} +function f1281(){} +function f1282(){} diff --git a/js/src/jit-test/tests/gc/bug-1311060.js b/js/src/jit-test/tests/gc/bug-1311060.js new file mode 100644 index 000000000..b4bdfd2d3 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1311060.js @@ -0,0 +1,3 @@ +if (helperThreadCount() === 0) + quit(); +evalInWorker(`schedulegc("s1");`); diff --git a/js/src/jit-test/tests/gc/bug-1313347.js b/js/src/jit-test/tests/gc/bug-1313347.js new file mode 100644 index 000000000..c5f684f7a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1313347.js @@ -0,0 +1,5 @@ +let tenured = {}; +gc(); +for (let i = 0; i < 100000; i++) { + tenured[i/2] = {}; +} diff --git a/js/src/jit-test/tests/gc/bug-1315946.js b/js/src/jit-test/tests/gc/bug-1315946.js new file mode 100644 index 000000000..d78c76eda --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1315946.js @@ -0,0 +1,14 @@ +if (!('oomTest' in this)) + quit(); + +// Don't run a full oomTest because it takes ages - a few iterations are +// sufficient to trigger the bug. +let i = 0; + +oomTest(Function(` + if (i < 10) { + i++; + gczeal(15,1); + foo; + } +`)); diff --git a/js/src/jit-test/tests/gc/bug-1321597.js b/js/src/jit-test/tests/gc/bug-1321597.js new file mode 100644 index 000000000..ff8efe530 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1321597.js @@ -0,0 +1,6 @@ +gczeal(9,3); +function test(s, okLine) { }; +var dbg = new Debugger; +dbg.onNewGlobalObject = function(global) {}; +x = evalcx(test()); +shortestPaths(this, ["\$4"], 5); diff --git a/js/src/jit-test/tests/gc/bug-1322420.js b/js/src/jit-test/tests/gc/bug-1322420.js new file mode 100644 index 000000000..5fcfe18e6 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1322420.js @@ -0,0 +1,8 @@ +options('strict_mode'); +var g1 = newGlobal(); +var g2 = newGlobal(); +var dbg = new Debugger(); +dbg.addDebuggee(g1); +g1.eval('function f() {}'); +gczeal(9, 1); +dbg.findScripts({}); diff --git a/js/src/jit-test/tests/gc/bug-1324512.js b/js/src/jit-test/tests/gc/bug-1324512.js new file mode 100644 index 000000000..b5720f742 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1324512.js @@ -0,0 +1,13 @@ +if (helperThreadCount() === 0) + quit(); + +evalInWorker(` + if (!('gczeal' in this)) + quit(); + try { + gczeal(2,1); + throw new Error(); + } catch (e) { + assertEq("" + e, "Error"); + } +`); diff --git a/js/src/jit-test/tests/gc/bug-1328251.js b/js/src/jit-test/tests/gc/bug-1328251.js new file mode 100644 index 000000000..fe8b962d5 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1328251.js @@ -0,0 +1,12 @@ +if (helperThreadCount() == 0) + quit(); + +evalInWorker(` + if (!('gczeal' in this)) + quit(); + gczeal(2); + for (let i = 0; i < 30; i++) { + var a = [1, 2, 3]; + a.indexOf(1); + relazifyFunctions(); } +`); diff --git a/js/src/jit-test/tests/gc/bug-1332773.js b/js/src/jit-test/tests/gc/bug-1332773.js new file mode 100644 index 000000000..e0e890c30 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1332773.js @@ -0,0 +1,10 @@ +if (helperThreadCount() == 0) + quit(); + +evalInWorker(` +var gTestcases = new Array(); +typeof document != "object" || !document.location.href.match(/jsreftest.html/); +gczeal(4, 10); +f = ([a = class target extends b {}, b] = [void 0]) => {}; +f() +`) diff --git a/js/src/jit-test/tests/gc/bug-1338383.js b/js/src/jit-test/tests/gc/bug-1338383.js new file mode 100644 index 000000000..f4b88634e --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1338383.js @@ -0,0 +1,16 @@ +// |jit-test| error: InternalError + +if (helperThreadCount() === 0) + throw InternalError(); + +var lfOffThreadGlobal = newGlobal(); +enableShellAllocationMetadataBuilder() +lfOffThreadGlobal.offThreadCompileScript(` + if ("gczeal" in this) + gczeal(8, 1) + function recurse(x) { + recurse(x + 1); + }; + recurse(0); +`); +lfOffThreadGlobal.runOffThreadScript(); diff --git a/js/src/jit-test/tests/gc/bug-1357022.js b/js/src/jit-test/tests/gc/bug-1357022.js new file mode 100644 index 000000000..4adae8dd0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1357022.js @@ -0,0 +1,6 @@ +const root3 = newGlobal(); +function test(constructor) { + if (!nukeCCW(root3.load)) {} +} +test(Map); +test(Set); diff --git a/js/src/jit-test/tests/gc/bug-787703.js b/js/src/jit-test/tests/gc/bug-787703.js new file mode 100644 index 000000000..bbc01bae7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-787703.js @@ -0,0 +1,7 @@ +// |jit-test| slow; + +eval(" function x() {}" + Array(241).join(" ")); +for (var i = 0; i < 100; i++) { + gczeal(4, 2); + String(x); +} diff --git a/js/src/jit-test/tests/gc/bug-820186.js b/js/src/jit-test/tests/gc/bug-820186.js new file mode 100644 index 000000000..cced86e20 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-820186.js @@ -0,0 +1,297 @@ +// |jit-test| slow;
+
+function randomRecursion() {
+ var y = ""
+ if (rnd(2)) {
+ var x = 2;
+ "{" + x + "}";
+ randomRecursion();
+ randomRecursion();
+ return [""];
+ }
+ return [""];
+}
+
+function thisFunctionIsNeverCalled() {
+}
+
+function testOne() {
+ ox = newGlobal();
+ var code = randomRecursion()[rnd(3)];
+}
+
+initRnd();
+gczeal(10, 3);
+
+for (var count = 0; count < 20; count++) {
+ print(count);
+ testOne()
+}
+
+// ==========================================================================================
+
+// this program is a JavaScript version of Mersenne Twister, with concealment and encapsulation in class,
+// an almost straight conversion from the original program, mt19937ar.c,
+// translated by y. okada on July 17, 2006.
+// Changes by Jesse Ruderman: added "var" keyword in a few spots; added export_mta etc; pasted into fuzz.js.
+// in this program, procedure descriptions and comments of original source code were not removed.
+// lines commented with //c// were originally descriptions of c procedure. and a few following lines are appropriate JavaScript descriptions.
+// lines commented with /* and */ are original comments.
+// lines commented with // are additional comments in this JavaScript version.
+// before using this version, create at least one instance of MersenneTwister19937 class, and initialize the each state, given below in c comments, of all the instances.
+/*
+ A C-program for MT19937, with initialization improved 2002/1/26.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
+ Before using, initialize the state by using init_genrand(seed)
+ or init_by_array(init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+*/
+
+function MersenneTwister19937()
+{
+ /* Period parameters */
+ //c//#define N 624
+ //c//#define M 397
+ //c//#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+ //c//#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+ //c//#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+ var N = 624;
+ var M = 397;
+ var MATRIX_A = 0x9908b0df; /* constant vector a */
+ var UPPER_MASK = 0x80000000; /* most significant w-r bits */
+ var LOWER_MASK = 0x7fffffff; /* least significant r bits */
+ //c//static unsigned long mt[N]; /* the array for the state vector */
+ //c//static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
+ var mt = new Array(N); /* the array for the state vector */
+ var mti = N+1; /* mti==N+1 means mt[N] is not initialized */
+
+ function unsigned32 (n1) // returns a 32-bits unsiged integer from an operand to which applied a bit operator.
+ {
+ return n1 < 0 ? (n1 ^ UPPER_MASK) + UPPER_MASK : n1;
+ }
+
+ function subtraction32 (n1, n2) // emulates lowerflow of a c 32-bits unsiged integer variable, instead of the operator -. these both arguments must be non-negative integers expressible using unsigned 32 bits.
+ {
+ return n1 < n2 ? unsigned32((0x100000000 - (n2 - n1)) & 0xffffffff) : n1 - n2;
+ }
+
+ function addition32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator +. these both arguments must be non-negative integers expressible using unsigned 32 bits.
+ {
+ return unsigned32((n1 + n2) & 0xffffffff)
+ }
+
+ function multiplication32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator *. these both arguments must be non-negative integers expressible using unsigned 32 bits.
+ {
+ var sum = 0;
+ for (var i = 0; i < 32; ++i){
+ if ((n1 >>> i) & 0x1){
+ sum = addition32(sum, unsigned32(n2 << i));
+ }
+ }
+ return sum;
+ }
+
+ /* initializes mt[N] with a seed */
+ //c//void init_genrand(unsigned long s)
+ this.init_genrand = function (s)
+ {
+ //c//mt[0]= s & 0xffffffff;
+ mt[0]= unsigned32(s & 0xffffffff);
+ for (mti=1; mti<N; mti++) {
+ mt[mti] =
+ //c//(1812433253 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+ addition32(multiplication32(1812433253, unsigned32(mt[mti-1] ^ (mt[mti-1] >>> 30))), mti);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array mt[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ //c//mt[mti] &= 0xffffffff;
+ mt[mti] = unsigned32(mt[mti] & 0xffffffff);
+ /* for >32 bit machines */
+ }
+ }
+
+ /* initialize by an array with array-length */
+ /* init_key is the array for initializing keys */
+ /* key_length is its length */
+ /* slight change for C++, 2004/2/26 */
+ //c//void init_by_array(unsigned long init_key[], int key_length)
+ this.init_by_array = function (init_key, key_length)
+ {
+ //c//int i, j, k;
+ var i, j, k;
+ //c//init_genrand(19650218);
+ this.init_genrand(19650218);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ //c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525))
+ //c// + init_key[j] + j; /* non linear */
+ mt[i] = addition32(addition32(unsigned32(mt[i] ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1664525)), init_key[j]), j);
+ mt[i] =
+ //c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
+ unsigned32(mt[i] & 0xffffffff);
+ i++; j++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ //c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941))
+ //c//- i; /* non linear */
+ mt[i] = subtraction32(unsigned32((dbg=mt[i]) ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1566083941)), i);
+ //c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
+ mt[i] = unsigned32(mt[i] & 0xffffffff);
+ i++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ }
+ mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
+ }
+
+ this.export_state = function() { return [mt, mti]; };
+ this.import_state = function(s) { mt = s[0]; mti = s[1]; };
+ this.export_mta = function() { return mt; };
+ this.import_mta = function(_mta) { mt = _mta };
+ this.export_mti = function() { return mti; };
+ this.import_mti = function(_mti) { mti = _mti; }
+
+ /* generates a random number on [0,0xffffffff]-interval */
+ //c//unsigned long genrand_int32(void)
+ this.genrand_int32 = function ()
+ {
+ //c//unsigned long y;
+ //c//static unsigned long mag01[2]={0x0UL, MATRIX_A};
+ var y;
+ var mag01 = new Array(0x0, MATRIX_A);
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ if (mti >= N) { /* generate N words at one time */
+ //c//int kk;
+ var kk;
+
+ if (mti == N+1) /* if init_genrand() has not been called, */
+ //c//init_genrand(5489); /* a default initial seed is used */
+ this.init_genrand(5489); /* a default initial seed is used */
+
+ for (kk=0;kk<N-M;kk++) {
+ //c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ //c//mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
+ y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
+ mt[kk] = unsigned32(mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1]);
+ }
+ for (;kk<N-1;kk++) {
+ //c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ //c//mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
+ y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
+ mt[kk] = unsigned32(mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1]);
+ }
+ //c//y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+ //c//mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
+ y = unsigned32((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK));
+ mt[N-1] = unsigned32(mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1]);
+ mti = 0;
+ }
+
+ y = mt[mti++];
+
+ /* Tempering */
+ //c//y ^= (y >> 11);
+ //c//y ^= (y << 7) & 0x9d2c5680;
+ //c//y ^= (y << 15) & 0xefc60000;
+ //c//y ^= (y >> 18);
+ y = unsigned32(y ^ (y >>> 11));
+ y = unsigned32(y ^ ((y << 7) & 0x9d2c5680));
+ y = unsigned32(y ^ ((y << 15) & 0xefc60000));
+ y = unsigned32(y ^ (y >>> 18));
+
+ return y;
+ }
+
+ /* generates a random number on [0,0x7fffffff]-interval */
+ //c//long genrand_int31(void)
+ this.genrand_int31 = function ()
+ {
+ //c//return (genrand_int32()>>1);
+ return (this.genrand_int32()>>>1);
+ }
+
+ /* generates a random number on [0,1]-real-interval */
+ //c//double genrand_real1(void)
+ this.genrand_real1 = function ()
+ {
+ //c//return genrand_int32()*(1.0/4294967295.0);
+ return this.genrand_int32()*(1.0/4294967295.0);
+ /* divided by 2^32-1 */
+ }
+
+ /* generates a random number on [0,1)-real-interval */
+ //c//double genrand_real2(void)
+ this.genrand_real2 = function ()
+ {
+ //c//return genrand_int32()*(1.0/4294967296.0);
+ return this.genrand_int32()*(1.0/4294967296.0);
+ /* divided by 2^32 */
+ }
+
+ /* generates a random number on (0,1)-real-interval */
+ //c//double genrand_real3(void)
+ this.genrand_real3 = function ()
+ {
+ //c//return ((genrand_int32()) + 0.5)*(1.0/4294967296.0);
+ return ((this.genrand_int32()) + 0.5)*(1.0/4294967296.0);
+ /* divided by 2^32 */
+ }
+
+ /* generates a random number on [0,1) with 53-bit resolution*/
+ //c//double genrand_res53(void)
+ this.genrand_res53 = function ()
+ {
+ //c//unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
+ var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6;
+ return(a*67108864.0+b)*(1.0/9007199254740992.0);
+ }
+ /* These real versions are due to Isaku Wada, 2002/01/09 added */
+}
+
+function initRnd() {
+ var fuzzMT = new MersenneTwister19937;
+ var fuzzSeed = 53;
+ fuzzMT.init_genrand(fuzzSeed);
+ rnd = function (n) { var v = Math.floor(fuzzMT.genrand_real2() * n); return v; };
+ rnd.rndReal = function() { return fuzzMT.genrand_real2(); };
+ rnd.fuzzMT = fuzzMT;
+}
diff --git a/js/src/jit-test/tests/gc/bug-821013.js b/js/src/jit-test/tests/gc/bug-821013.js new file mode 100644 index 000000000..f086fb402 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-821013.js @@ -0,0 +1,6 @@ +for each(let c in [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, ({'0': 0}) +]) {} + diff --git a/js/src/jit-test/tests/gc/bug-821551.js b/js/src/jit-test/tests/gc/bug-821551.js new file mode 100644 index 000000000..8d13799bf --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-821551.js @@ -0,0 +1,16 @@ +function g() { + z = newGlobal(''); + return function(code) { + evalcx(code, z) + } +} +f = g(); +f("\ + options('strict_mode');\ + for (var x = 0; x < 1; ++x) {\ + a = x;\ + }\ + options('strict_mode');\ +"); +f("a in eval"); + diff --git a/js/src/jit-test/tests/gc/bug-824321.js b/js/src/jit-test/tests/gc/bug-824321.js new file mode 100644 index 000000000..424e2db0c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-824321.js @@ -0,0 +1,3 @@ +x = "\udada\udada"; +gc(); + diff --git a/js/src/jit-test/tests/gc/bug-825326.js b/js/src/jit-test/tests/gc/bug-825326.js new file mode 100644 index 000000000..1579f1d29 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-825326.js @@ -0,0 +1,18 @@ +// |jit-test| + +try { + a = [] + r = /x/ + gczeal(10, 2)() +} catch (e) {} +try { + (function() { + r(function() { + eval() + }) + })() +} catch (e) {} +try { + s +} catch (e) {} +a.every(function() {}) diff --git a/js/src/jit-test/tests/gc/bug-832103.js b/js/src/jit-test/tests/gc/bug-832103.js new file mode 100644 index 000000000..e6e0e2a92 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-832103.js @@ -0,0 +1,27 @@ +//|jit-test| error:TypeError +RegExp("").exec() +Object.defineProperty(this, "x", { + get: function() { + return new Array + } +}) +Object.defineProperty(this, "y", { + get: function() { + return [function() {}, 0, 0, 0, 0, 0, 0] + } +}) +r = RegExp(""); +uneval(undefined) +with({ + b: gczeal(9, 2) +}); +r = /()/; +y.sort(function(j) { + if (j) { + a = + new + Array + } else { + x.v() + } +}) diff --git a/js/src/jit-test/tests/gc/bug-880816.js b/js/src/jit-test/tests/gc/bug-880816.js new file mode 100644 index 000000000..7d7e9e622 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-880816.js @@ -0,0 +1,30 @@ +var lfcode = new Array(); +lfcode.push("const baz = 'bar';"); +lfcode.push("2"); +lfcode.push("{ function foo() {} }"); +lfcode.push("evaluate('\ +var INVALIDATE_MODES = INVALIDATE_MODE_STRINGS.map(s => ({mode: s}));\ +function range(n, m) {}\ +function seq_scan(array, f) {}\ +function assertStructuralEq(e1, e2) {}\ +for (var i = 0, l = a.length; i < l; i++) {}\ +');"); +lfcode.push("for (var x of new Set(Object.getOwnPropertyNames(this))) {}"); +var lfRunTypeId = -1; +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + try { + if (lfVarx.substr(-3) == ".js") {} + if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } else { + switch (lfRunTypeId) { + case 2: new Function(lfVarx)(); break; + default: evaluate(lfVarx); break; + } + } + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/gc/bug-880886.js b/js/src/jit-test/tests/gc/bug-880886.js new file mode 100644 index 000000000..2f83a2c63 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-880886.js @@ -0,0 +1,10 @@ +// |jit-test| error: too much recursion + +function testUniqueness(asmJSModule) { + var f = asmJSModule(); +} +function lambda() { + var x = function inner() { "use asm"; function g() {} return g }; + return lambda(); +} +testUniqueness(lambda); diff --git a/js/src/jit-test/tests/gc/bug-886551-1.js b/js/src/jit-test/tests/gc/bug-886551-1.js new file mode 100644 index 000000000..b3f2bcd45 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-886551-1.js @@ -0,0 +1,8 @@ +if (this.hasOwnProperty('Intl')) { + gc(); + gcslice(1); + var thisValues = [ "x" ]; + thisValues.forEach(function (value) { + var format = Intl.DateTimeFormat.call(value); + }); +} diff --git a/js/src/jit-test/tests/gc/bug-886551-2.js b/js/src/jit-test/tests/gc/bug-886551-2.js new file mode 100644 index 000000000..9381c867d --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-886551-2.js @@ -0,0 +1,7 @@ +gc(); +gcslice(1); +function isClone(a, b) { + var rmemory = new WeakMap(); + rmemory.set(a,b); +} +isClone([]); diff --git a/js/src/jit-test/tests/gc/bug-886560.js b/js/src/jit-test/tests/gc/bug-886560.js new file mode 100644 index 000000000..c506b05d0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-886560.js @@ -0,0 +1,11 @@ +// |jit-test| error: x is not defined + +// enableShellAllocationMetadataBuilder ignores its argument, because we don't +// permit metadata callbacks to run JS any more, so this test may be +// unnecessary. We'll preserve its structure just in case. +enableShellAllocationMetadataBuilder(function(obj) { + var res = {}; + return res; + }); +gczeal(4); +x(); diff --git a/js/src/jit-test/tests/gc/bug-886630.js b/js/src/jit-test/tests/gc/bug-886630.js new file mode 100644 index 000000000..e7d7203fe --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-886630.js @@ -0,0 +1,112 @@ +function errorToString(e) { + try {} catch (e2) {} +} +Object.getOwnPropertyNames(this); +if (false) { + for (let x of constructors) + print(x); +} +var tryRunning = tryRunningDirectly; +function unlikelyToHang(code) { + var codeL = code.replace(/\s/g, " "); + return true && code.indexOf("infloop") == -1 && !(codeL.match(/const.*for/)) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); } + && !(codeL.match(/for.*const/)) // can be an infinite loop: for each(x in ...); const x; + && !(codeL.match(/for.*in.*uneval/)) // can be slow to loop through the huge string uneval(this), for example + && !(codeL.match(/for.*for.*for/)) // nested for loops (including for..in, array comprehensions, etc) can take a while + && !(codeL.match(/for.*for.*gc/)) +} +function whatToTestSpidermonkeyTrunk(code) { + var codeL = code.replace(/\s/g, " "); + return { + allowParse: true, + allowExec: unlikelyToHang(code), + allowIter: true, + expectConsistentOutput: true && code.indexOf("Date") == -1 // time marches on + && code.indexOf("random") == -1 && code.indexOf("dumpObject") == -1 // shows heap addresses + && code.indexOf("oomAfterAllocations") == -1 && code.indexOf("ParallelArray") == -1, + expectConsistentOutputAcrossIter: true && code.indexOf("options") == -1 // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment + , + expectConsistentOutputAcrossJITs: true && code.indexOf("'strict") == -1 // bug 743425 + && code.indexOf("preventExtensions") == -1 // bug 887521 + && !(codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?) + }; +} +function tryRunningDirectly(f, code, wtt) { + try { + eval(code); + } catch (e) {} + try { + var rv = f(); + tryIteration(rv); + } catch (runError) { + var err = errorToString(runError); + } + tryEnsureSanity(); +} +var realEval = eval; +var realMath = Math; +var realFunction = Function; +var realGC = gc; +var realUneval = uneval; +function tryEnsureSanity() { + try { + delete this.Math; + delete this.Function; + delete this.gc; + delete this.uneval; + this.Math = realMath; + this.eval = realEval; + this.Function = realFunction; + this.gc = realGC; + this.uneval = realUneval; + } catch (e) {} +} +function tryIteration(rv) { + try { + var iterCount = 0; + for /* each */ + ( /* let */ iterValue in rv) + print("Iterating succeeded, iterCount == " + iterCount); + } catch (iterError) {} +} +function failsToCompileInTry(code) { + try { + new Function(" try { " + code + " } catch(e) { }"); + } catch (e) {} +} +function tryItOut(code) { + if (count % 1000 == 0) { + gc(); + } + var wtt = whatToTestSpidermonkeyTrunk(code); + code = code.replace(/\/\*DUPTRY\d+\*\//, function(k) { + var n = parseInt(k.substr(8), 10); + print(n); + return strTimes("try{}catch(e){}", n); + }) + try { + f = new Function(code); + } catch (compileError) {} + if (code.indexOf("\n") == -1 && code.indexOf("\r") == -1 && code.indexOf("\f") == -1 && code.indexOf("\0") == -1 && code.indexOf("\u2028") == -1 && code.indexOf("\u2029") == -1 && code.indexOf("<--") == -1 && code.indexOf("-->") == -1 && code.indexOf("//") == -1) { + var nCode = code; + if (nCode.indexOf("return") != -1 || nCode.indexOf("yield") != -1 || nCode.indexOf("const") != -1 || failsToCompileInTry(nCode)) nCode = "(function(){" + nCode + "})()" + } + tryRunning(f, code, false); +} +var count = 0; +tryItOut(""); +count = 2 +tryItOut(""); +tryItOut(""); +tryItOut("o") +tryItOut("") +tryItOut("") +tryItOut("\ + with((/ /-7))\ + {\ + for(let mjcpxc=0;mjcpxc<9;++mjcpxc)\ + {\ + e=mjcpxc;\ + yield/x/\ + }}") + diff --git a/js/src/jit-test/tests/gc/bug-889682-1.js b/js/src/jit-test/tests/gc/bug-889682-1.js new file mode 100644 index 000000000..75b3f4089 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-889682-1.js @@ -0,0 +1,13 @@ +// |jit-test| error:TypeError +gc(); +var recursiveFunctions = [{ + text: "(function(){if(a){}g()})" +}]; +(function testAllRecursiveFunctions() { + for (var i = 0; i < recursiveFunctions.length; ++i) { + var a = recursiveFunctions[i]; + eval(a.text.replace(/@/g, "")) + } +})(); +gcslice(2869); +Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")() diff --git a/js/src/jit-test/tests/gc/bug-889682-2.js b/js/src/jit-test/tests/gc/bug-889682-2.js new file mode 100644 index 000000000..efc47337a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-889682-2.js @@ -0,0 +1,14 @@ +// |jit-test| error:TypeError +(function(){}) +gc(); +var recursiveFunctions = [{ + text: "(function(){if(a){}g()})" +}]; +(function testAllRecursiveFunctions() { + for (var i = 0; i < recursiveFunctions.length; ++i) { + var a = recursiveFunctions[i]; + eval(a.text.replace(/@/g, "")) + } +})(); +gcslice(2869); +Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")() diff --git a/js/src/jit-test/tests/gc/bug-889682-3.js b/js/src/jit-test/tests/gc/bug-889682-3.js new file mode 100644 index 000000000..601c8300a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-889682-3.js @@ -0,0 +1,14 @@ +// |jit-test| error:TypeError +function f(){} +gc(); +var recursiveFunctions = [{ + text: "(function(){if(a){}g()})" +}]; +(function testAllRecursiveFunctions() { + for (var i = 0; i < recursiveFunctions.length; ++i) { + var a = recursiveFunctions[i]; + eval(a.text.replace(/@/g, "")) + } +})(); +gcslice(2869); +Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")() diff --git a/js/src/jit-test/tests/gc/bug-891773.js b/js/src/jit-test/tests/gc/bug-891773.js new file mode 100644 index 000000000..c5cb23778 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-891773.js @@ -0,0 +1,14 @@ +x = newGlobal() +Int32Array = x.Int32Array +x.p = new ArrayBuffer() +schedulegc(29); +(function(stdlib, n, heap) { + "use asm" + var Int32ArrayView = new stdlib.Int32Array(heap) + function f() { + Int32ArrayView[1] + } + return f +})(this, { + f: new Function +}, new ArrayBuffer()) diff --git a/js/src/jit-test/tests/gc/bug-900405.js b/js/src/jit-test/tests/gc/bug-900405.js new file mode 100644 index 000000000..eeec6f25f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-900405.js @@ -0,0 +1,3 @@ +(function() { + [{ "9": [] }.watch([], function(){})] +})() diff --git a/js/src/jit-test/tests/gc/bug-906236.js b/js/src/jit-test/tests/gc/bug-906236.js new file mode 100644 index 000000000..7566bda42 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-906236.js @@ -0,0 +1,9 @@ +// |jit-test| error: too much recursion +(function() { + (function f(x) { + return x * f(x - 1); + with({}) + var r = "" + })() +})() + diff --git a/js/src/jit-test/tests/gc/bug-906241.js b/js/src/jit-test/tests/gc/bug-906241.js new file mode 100644 index 000000000..ccbc73e59 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-906241.js @@ -0,0 +1,9 @@ +// |jit-test| error: InternalError: too much recursion +for (let y in []); +(function f(x) { + new Float64Array(new ArrayBuffer()); + { + f(x) + function t() {} + } +})(); diff --git a/js/src/jit-test/tests/gc/bug-906243.js b/js/src/jit-test/tests/gc/bug-906243.js new file mode 100644 index 000000000..a9006f18c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-906243.js @@ -0,0 +1,12 @@ +a2 = [] +g = function() r +Object.defineProperty(a2, 0, { + set: function() {} +}) +for (var x = 0; x < 70; ++x) { + Array.prototype.unshift.call(a2, g) +} +a2.length = 8 +for each(e in [0, 0]) { + Array.prototype.shift.call(a2) +} diff --git a/js/src/jit-test/tests/gc/bug-912734.js b/js/src/jit-test/tests/gc/bug-912734.js new file mode 100644 index 000000000..86a09a1df --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-912734.js @@ -0,0 +1,43 @@ +(function() { + Object.defineProperty(this, "h2", { + e: false, + e: false, + get: function() { + return {} + } + }) +})() +a2 = new Array +Object.create(a2); +(function() { + Object.defineProperty(this, "t2", { + e: true, + e: RegExp(""), + get: function() { + return new Uint32Array(this.a2) + } + }) +})() +r = (function() { + for each(let c in []) {} +})() +var r = 1; +s = "" +print(s.match(r)); +r.l +with(b = 3); +t2; +(function() { + Object.defineProperty(a2, 3, { + e: false, + e: true, + get: (function() { + evalcx("[]", s.g) + }) + }) +})() +h2 +r = RegExp(""); +r.exec(); +schedulegc(7); +t2; diff --git a/js/src/jit-test/tests/gc/bug-912813.js b/js/src/jit-test/tests/gc/bug-912813.js new file mode 100644 index 000000000..1babaac28 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-912813.js @@ -0,0 +1,7 @@ +// |jit-test| slow +gczeal(9, 1) +for (var a = 0; a < 1; a++) { + newGlobal({ + sameZoneAs: {} + }) +} diff --git a/js/src/jit-test/tests/gc/bug-913224.js b/js/src/jit-test/tests/gc/bug-913224.js new file mode 100644 index 000000000..815164d76 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-913224.js @@ -0,0 +1 @@ +dumpHeap(); diff --git a/js/src/jit-test/tests/gc/bug-913261.js b/js/src/jit-test/tests/gc/bug-913261.js new file mode 100644 index 000000000..43066053f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-913261.js @@ -0,0 +1,5 @@ +// |jit-test| error: InternalError: too much recursion +(function f() { + "".watch(2, function() {}); + f(); +})() diff --git a/js/src/jit-test/tests/gc/bug-913715.js b/js/src/jit-test/tests/gc/bug-913715.js new file mode 100644 index 000000000..3a05cf588 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-913715.js @@ -0,0 +1,31 @@ +try { + (function() { + Object.defineProperty(this, "x", { + get: function() { + Object.defineProperty(this, "y", { + configurable: true, + get: function() { + return Proxy(this.y) + } + }); + x; + } + }) + })() + x +} catch (e) {} +try { + x +} catch (e) {} +try { + x +} catch (e) {} +try { + y +} catch (e) {} +try { + y +} catch (e) {} +try { + y +} catch (e) {} diff --git a/js/src/jit-test/tests/gc/bug-919536.js b/js/src/jit-test/tests/gc/bug-919536.js new file mode 100644 index 000000000..0c07b4b59 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-919536.js @@ -0,0 +1,17 @@ +if ("gczeal" in this) { + gczeal(2, 1000); + + var a = new Array(10 * 1000); + + var i = a.length; + while (i-- != 0) { + switch (i % 3) { + case 0: + a[i] = { }; + break; + } + } + + gc(); +} + diff --git a/js/src/jit-test/tests/gc/bug-924690.js b/js/src/jit-test/tests/gc/bug-924690.js new file mode 100644 index 000000000..e7fdc981b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-924690.js @@ -0,0 +1,25 @@ +x = [] +try { + (function() { + schedulegc(1); + ((function() { + return { + y: function() { + u() = [] + } + } + })()) + })() + watch.call(x, "valueOf", function() {}) + gc() +} catch (e) { print(e); } +try { + (function() { + x.valueOf = + (function() { + y(); + }) + })() + x + 2 + print('foo') +} catch (e) { print(e); } diff --git a/js/src/jit-test/tests/gc/bug-935022.js b/js/src/jit-test/tests/gc/bug-935022.js new file mode 100644 index 000000000..2ebe14891 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-935022.js @@ -0,0 +1,4 @@ +function callback(obj) {} +enableShellAllocationMetadataBuilder(); +gczeal(7); +var statusitems = []; diff --git a/js/src/jit-test/tests/gc/bug-939499.js b/js/src/jit-test/tests/gc/bug-939499.js new file mode 100644 index 000000000..b0f683b58 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-939499.js @@ -0,0 +1,4 @@ +gczeal(0); +gc(); +verifyprebarriers(); +gcparam('markStackLimit', 5); diff --git a/js/src/jit-test/tests/gc/bug-945275.js b/js/src/jit-test/tests/gc/bug-945275.js new file mode 100644 index 000000000..42e63a55c --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-945275.js @@ -0,0 +1,11 @@ +function TestCase(n) { + this.name = undefined; + this.description = undefined; +} +gczeal(7,1); +eval("\ +function reportCompare() new TestCase;\ +reportCompare();\ +Object.defineProperty(Object.prototype, 'name', {});\ +reportCompare();\ +"); diff --git a/js/src/jit-test/tests/gc/bug-945280.js b/js/src/jit-test/tests/gc/bug-945280.js new file mode 100644 index 000000000..3546c864d --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-945280.js @@ -0,0 +1,4 @@ +gczeal(7,1); +enableShellAllocationMetadataBuilder(); +gczeal(false); +var statusitems = []; diff --git a/js/src/jit-test/tests/gc/bug-945285.js b/js/src/jit-test/tests/gc/bug-945285.js new file mode 100644 index 000000000..7544d86c0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-945285.js @@ -0,0 +1,3 @@ +gczeal(11); +function callback(obj) {} +enableShellAllocationMetadataBuilder(); diff --git a/js/src/jit-test/tests/gc/bug-948423.js b/js/src/jit-test/tests/gc/bug-948423.js new file mode 100644 index 000000000..702bedb28 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-948423.js @@ -0,0 +1,23 @@ +if (!this.hasOwnProperty("TypedObject")) + quit(); + +var ArrayType = TypedObject.ArrayType; +var StructType = TypedObject.StructType; +var uint8 = TypedObject.uint8; +var uint32 = TypedObject.uint32; +var ObjectType = TypedObject.Object; +function runTests() { + (function DimensionLinkedToUndimension() { + var FiveUintsA = uint32.array(5); + var FiveUintsB = uint32.array(5); + assertEq(true, + FiveUintsA.equivalent(FiveUintsB) + ); + })(); + (function PrototypeHierarchy() { + schedulegc(3); + var Uint8s = uint8.array(5); + })(); +} + +runTests(); diff --git a/js/src/jit-test/tests/gc/bug-950927.js b/js/src/jit-test/tests/gc/bug-950927.js new file mode 100644 index 000000000..23096c483 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-950927.js @@ -0,0 +1,31 @@ +var lfcode = new Array(); +lfcode.push("\ +var optionNames = options().split(',');\ + for (var i = 0; i < optionNames.length; i++) {}\ +"); +lfcode.push("gczeal(7,5);"); +lfcode.push("4"); +lfcode.push("\ +var S = new Array();\ +var x = 1;\ +for ( var i = 8; i >= 0; i-- ) {\ + S[0] += ' ';\ + S[0] += ',';\ +}\ +eval(S);\ +"); +var lfRunTypeId = -1; +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + switch (lfRunTypeId) { + case 4: eval("(function() { " + lfVarx + " })();"); break; + default: evaluate(lfVarx, { noScriptRval : true }); break; + } + } else if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } +} diff --git a/js/src/jit-test/tests/gc/bug-952819.js b/js/src/jit-test/tests/gc/bug-952819.js new file mode 100644 index 000000000..3b118a2dc --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-952819.js @@ -0,0 +1,3 @@ +verifypostbarriers() +verifyprebarriers() +verifypostbarriers() diff --git a/js/src/jit-test/tests/gc/bug-956324.js b/js/src/jit-test/tests/gc/bug-956324.js new file mode 100644 index 000000000..3fd9001f8 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-956324.js @@ -0,0 +1,28 @@ +var g = newGlobal(); +g.eval("function f() {\n" + + " debugger;\n" + + "}\n") + +var dbg = new Debugger(g); +var handler = {}; +dbg.onDebuggerStatement = function (frame) { + frame.script.setBreakpoint(0, {}); +}; + +// create breakpoint +g.f() + +// drop our references to things +handler = undefined; +dbg.onDebuggerStatement = undefined; + +dbg.removeAllDebuggees(); + +gc(); + +//create garbage to trigger a minor GC +var x; +for (var i = 0; i < 100; ++i) + x = {}; + +gc(); diff --git a/js/src/jit-test/tests/gc/bug-957110.js b/js/src/jit-test/tests/gc/bug-957110.js new file mode 100644 index 000000000..0a0ce489a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-957110.js @@ -0,0 +1,6 @@ +gczeal(7,1); +try { +gcparam("maxBytes", gcparam("gcBytes") + 4*1024); +newGlobal("same-compartment"); +} catch(exc1) {} +gczeal(1); diff --git a/js/src/jit-test/tests/gc/bug-957114.js b/js/src/jit-test/tests/gc/bug-957114.js new file mode 100644 index 000000000..f245786b9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-957114.js @@ -0,0 +1,13 @@ +gczeal(7,1); +function TestCase(n) { + this.name = ''; + this.description = ''; + this.expect = ''; + this.actual = ''; + this.reason = ''; + this.passed = ''; +} +function test() new TestCase; +test(); +Object.defineProperty(Object.prototype, "name", {}); +test(); diff --git a/js/src/jit-test/tests/gc/bug-961741.js b/js/src/jit-test/tests/gc/bug-961741.js new file mode 100644 index 000000000..c4c782363 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-961741.js @@ -0,0 +1,5 @@ +function r() { + for (var x in undefined) {} +} +enableShellAllocationMetadataBuilder(); +r(); diff --git a/js/src/jit-test/tests/gc/bug-961877.js b/js/src/jit-test/tests/gc/bug-961877.js new file mode 100644 index 000000000..697f6c197 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-961877.js @@ -0,0 +1,14 @@ +g = Function("", "for (var i = 0; i < 0; ++i) { eval('this.arg'+0 +'=arg'+0); }"); +Math.abs(undefined); +gczeal(2,300); +evaluate("\ +var toFloat32 = (function() {\ + var f32 = new Float32Array(1);\ + function f(x) f32[0] = x;\ + return f;\ +})();\ +for (var i = 0; i < 64; ++i) {\ + var p = Math.pow(2, i) + 1;\ + g(toFloat32(p));\ + toFloat32(-p);\ +}"); diff --git a/js/src/jit-test/tests/gc/bug-969012.js b/js/src/jit-test/tests/gc/bug-969012.js new file mode 100644 index 000000000..ed03f66a7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-969012.js @@ -0,0 +1,60 @@ +function testClosureCreationAndInvocation() { + var a = 'foobar'; + function makeaddv(vvvv) { + var z = -4 * vvvv; + var y = -3 * vvvv; + var x = -2 * vvvv; + var w = -1 * vvvv; + var v = 0 * vvvv; + var u = 1 * vvvv; + var t = 2 * vvvv; + var s = 3 * vvvv; + var r = 4 * vvvv; + var q = 5 * vvvv; + var p = 6 * vvvv; + var o = 7 * vvvv; + var n = 8 * vvvv; + var m = 9 * vvvv; + var l = 10 * vvvv; + var k = 11 * vvvv; + var j = 12 * vvvv; + var i = 13 * vvvv; + var h = 14 * vvvv; + var g = 15 * vvvv; + var f = 16 * vvvv; + var e = 17 * vvvv; + var d = 18 * vvvv; + var c = 19 * vvvv; + var b = 20 * vvvv; + var a = 21 * vvvv; + return function (x) { + switch (x) { + case 0: return a; case 1: return b; + case 2: return c; case 3: return d; + case 4: return e; case 5: return f; + case 6: return g; case 7: return h; + case 8: return i; case 9: return j; + case 10: return k; case 11: return l; + case 12: return m; case 13: return n; + case 14: return o; case 15: return p; + case 16: return q; case 17: return r; + case 18: return s; case 19: return t; + case 20: return u; case 21: return v; + case 22: return w; case 23: return x; + case 24: return y; case 25: return z; + } + }; + } + var a = Array(); + for (var i = 0; i < 26; ++i) { + a.push(makeaddv(Math.random())); + } + return a; +} + +var a = testClosureCreationAndInvocation(); +for (var i = 0; i < 26; ++i) { + print(a[i](i)); +} + + diff --git a/js/src/jit-test/tests/gc/bug-978353.js b/js/src/jit-test/tests/gc/bug-978353.js new file mode 100644 index 000000000..44635209f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-978353.js @@ -0,0 +1,6 @@ +var arr = new Float64Array(2); +function test(m) { + arr[1] = m; +} +for(var i=0; i<20000; ++i, Array('x')) + test(0); diff --git a/js/src/jit-test/tests/gc/bug-978802.js b/js/src/jit-test/tests/gc/bug-978802.js new file mode 100644 index 000000000..33c2012ec --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-978802.js @@ -0,0 +1,18 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + try { + var max = 400; + function f(b) { + if (b) { + f(b - 1); + } else { + g = {}; + } + g.apply(null, arguments); + } + f(max - 1); + } catch(exc0) {} + f(); +}); diff --git a/js/src/jit-test/tests/gc/bug-981289.js b/js/src/jit-test/tests/gc/bug-981289.js new file mode 100644 index 000000000..edba3fc97 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-981289.js @@ -0,0 +1,8 @@ +gcPreserveCode(); +function test() { + for (var i=0; i<20; i++) { + arguments.x = {}; + gc(); + } +} +test(); diff --git a/js/src/jit-test/tests/gc/bug-981295.js b/js/src/jit-test/tests/gc/bug-981295.js new file mode 100644 index 000000000..691c06bde --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-981295.js @@ -0,0 +1,9 @@ +var NotEarlyErrorString = "NotEarlyError"; +var NotEarlyError = new Error(NotEarlyErrorString); +var juneDate = new Date(2000, 5, 20, 0, 0, 0, 0); +for (var i = 0; i < function(x) myObj(Date.prototype.toString.apply(x)); void i) { + eval(a.text.replace(/@/g, "")) +} +gcslice(2601); +function testcase() {} +new Uint16Array(testcase); diff --git a/js/src/jit-test/tests/gc/bug-985732.js b/js/src/jit-test/tests/gc/bug-985732.js new file mode 100644 index 000000000..eb560f187 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-985732.js @@ -0,0 +1,84 @@ +// |jit-test| error: expected is not defined +function testx() { +function compareArray(aExpected, aActual) {} + for (var i = 0; i < expected.length; i++) {} +var supportsArrayIndexGettersOnArrays = undefined; +function fnSupportsArrayIndexGettersOnArrays() {} +var supportsArrayIndexGettersOnObjects = undefined; +function fnSupportsArrayIndexGettersOnObjects() {} +function ConvertToFileUrl(pathStr) { +} +function fnExists() {} +var __globalObject = Function("return this;")(); +function fnGlobalObject() {} +function fnSupportsStrict() { + eval('with ({}) {}'); +} +function dataPropertyAttributesAreCorrect(obj, configurable) {} +function accessorPropertyAttributesAreCorrect(obj, configurable) {} +var NotEarlyErrorString = "NotEarlyError"; +var EarlyErrorRePat = "^((?!" + NotEarlyErrorString + ").)*$"; +var NotEarlyError = new Error(NotEarlyErrorString); +function Test262Error(message) {}; +function testFailed(message) {} +function testPrint(message) {} +function $PRINT(message) {} +function $INCLUDE(message) { } +function $ERROR(message) {} +function $FAIL(message) {} +function getPrecision(num) {} +var prec; +function isEqual(num1, num2) {} +function ToInteger(p) {} +var HoursPerDay = 24; +var MinutesPerHour = 60; +var SecondsPerMinute = 60; +var msPerDay = 86400000; +var msPerSecond = 1000; +var msPerMinute = 60000; +var msPerHour = 3600000; +var date_1899_end = -2208988800001; +var date_1900_start = -2208988800000; +var date_1969_end = -1; +var date_1970_start = 0; +var date_1999_end = 946684799999; +var date_2000_start = 946684800000; +var date_2099_end = 4102444799999; +var date_2100_start = 4102444800000; +var $LocalTZ, + $DST_start_month, + $DST_start_sunday, + $DST_start_hour, + $DST_start_minutes, + $DST_end_month, + $DST_end_sunday, + $DST_end_hour, + $DST_end_minutes; +function Day(t) {} +function TimeWithinDay(t) {} +function DaysInYear(y){} +function DayFromYear(y) {} +function TimeFromYear(y){} +function YearFromTime(t) {} +function InLeapYear(t){} +function DayWithinYear(t) {} +function MonthFromTime(t){} +function DateFromTime(t) {} +function WeekDay(t) {} +var LocalTZA = $LocalTZ*msPerHour; +function DaysInMonth(m, leap) {} +function GetSundayInMonth(t, m, count){} +function DaylightSavingTA(t) {} +function LocalTime(t){} +function UTC(t) {} +function HourFromTime(t){} +function MinFromTime(t){} +function SecFromTime(t){} +function msFromTime(t){} +function MakeTime(hour, min, sec, ms){} +function MakeDay(year, month, date) {} +function MakeDate( day, time ) {} +function TimeClip(time) {} +function ConstructDate(year, month, date, hours, minutes, seconds, ms){} +function runTestCase(testcase) {} +} testx(); diff --git a/js/src/jit-test/tests/gc/bug-986864.js b/js/src/jit-test/tests/gc/bug-986864.js new file mode 100644 index 000000000..abb8de6b2 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-986864.js @@ -0,0 +1,8 @@ +// |jit-test| slow +function x() {} +for (var j = 0; j < 9999; ++j) { + (function() { + x += x.watch("endsWith", ArrayBuffer); + return 0 >> Function(x) + })() +} diff --git a/js/src/jit-test/tests/gc/bug-993768.js b/js/src/jit-test/tests/gc/bug-993768.js new file mode 100644 index 000000000..2fc05fb5b --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-993768.js @@ -0,0 +1,13 @@ +var SECTION = ""; +gcPreserveCode() +gczeal(9, 1000); +function test() { + var f32 = new Float32Array(10); + f32[0] = 5; + var i = 0; + for (var j = 0; j < 10000; ++j) { + f32[i + 1] = f32[i] - 1; + SECTION += 1; + } +} +test(); diff --git a/js/src/jit-test/tests/gc/bug1116306.js b/js/src/jit-test/tests/gc/bug1116306.js new file mode 100644 index 000000000..83562f4d9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1116306.js @@ -0,0 +1,8 @@ +const dbg = new Debugger(); +const g = newGlobal(); +dbg.addDebuggee(g); +dbg.memory.trackingAllocationSites = true; +g.eval("this.alloc = {}"); +verifyprebarriers(); +schedulegc(3); +dbg.memory.drainAllocationsLog(); diff --git a/js/src/jit-test/tests/gc/bug1191756.js b/js/src/jit-test/tests/gc/bug1191756.js new file mode 100644 index 000000000..b52203a9d --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1191756.js @@ -0,0 +1,19 @@ +if (typeof 'oomAtAllocation' === 'undefined') + quit(); + +function fn(i) { + if (i == 3) + return ["isFinite"].map(function (i) {}); + return []; +} + +try { + fn(0); + fn(1); + fn(2); + oomAtAllocation(50); + fn(3); +} catch(e) { + // Ignore oom +} + diff --git a/js/src/jit-test/tests/gc/bug1246607.js b/js/src/jit-test/tests/gc/bug1246607.js new file mode 100644 index 000000000..a1ab10660 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1246607.js @@ -0,0 +1,16 @@ +if (typeof oomTest !== 'function' || typeof Intl !== 'object') + quit(); + +oomTest(() => { + try { + new Intl.DateTimeFormat; + x1 = 0; + } catch (e) { + switch (1) { + case 0: + let s; + case 1: + x; + } + } +}) diff --git a/js/src/jit-test/tests/gc/bug1282113.js b/js/src/jit-test/tests/gc/bug1282113.js new file mode 100644 index 000000000..88d128a0f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1282113.js @@ -0,0 +1,6 @@ +Object.getOwnPropertyNames(this); +setGCCallback({ + action: "majorGC", + phases: "begin" +}); +selectforgc(this); diff --git a/js/src/jit-test/tests/gc/bug1283169.js b/js/src/jit-test/tests/gc/bug1283169.js new file mode 100644 index 000000000..aa6802bb0 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1283169.js @@ -0,0 +1,4 @@ +if (helperThreadCount() === 0) + quit(0); +startgc(45); +offThreadCompileScript("print(1)"); diff --git a/js/src/jit-test/tests/gc/bug1285186.js b/js/src/jit-test/tests/gc/bug1285186.js new file mode 100644 index 000000000..d04f98a45 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1285186.js @@ -0,0 +1,6 @@ +if (helperThreadCount() === 0) + quit(); +gczeal(10); +newGlobal(); +offThreadCompileScript("let x = 1;"); +abortgc(); diff --git a/js/src/jit-test/tests/gc/bug1285490.js b/js/src/jit-test/tests/gc/bug1285490.js new file mode 100644 index 000000000..02bf4b56a --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1285490.js @@ -0,0 +1,4 @@ +if (helperThreadCount() === 0) + quit(); +gczeal(4); +offThreadCompileScript("let x = 1;"); diff --git a/js/src/jit-test/tests/gc/bug1287063.js b/js/src/jit-test/tests/gc/bug1287063.js new file mode 100644 index 000000000..557f84933 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug1287063.js @@ -0,0 +1,4 @@ +if (helperThreadCount() === 0) + quit(); +schedulegc(""); +offThreadCompileScript(""); diff --git a/js/src/jit-test/tests/gc/bug888463.js b/js/src/jit-test/tests/gc/bug888463.js new file mode 100644 index 000000000..cd7e170d2 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug888463.js @@ -0,0 +1,66 @@ +var sjcl = { + hash: {}, +}; +sjcl.bitArray = { + concat: function (a, b) { + var c = a[a.length - 1], + d = sjcl.bitArray.getPartial(c); + return d === 32 ? a.concat(b) : sjcl.bitArray.P(b, d, c | 0, a.slice(0, a.length - 1)) + }, + getPartial: function (a) { + return Math.round(a / 0x10000000000) || 32 + } +}; +sjcl.hash.sha256 = function (a) { + this.a[0] || this.w(); + this.reset() +}; +sjcl.hash.sha256.prototype = { + reset: function () { + this.n = this.N.slice(0); + this.i = []; + }, + update: function (a) { + var b, c = this.i = sjcl.bitArray.concat(this.i, a); + return this + }, + finalize: function () { + var a, b = this.i, + c = this.n; + this.C(b.splice(0, 16)); + return c + }, + N: [], + a: [], + w: function () { + function a(e) { + return (e - Math.floor(e)) * 0x100000000 | 0 + } + var b = 0, + c = 2, + d; + a: for (; b < 64; c++) { + if (b < 8) + this.N[b] = a(Math.pow(c, 0.5)); + b++ + } + }, + C: function (a) { + var b, c, d = a.slice(0), + e = this.n, + h = e[1], + i = e[2], + k = e[3], + n = e[7]; + for (a = 0; a < 64; a++) { + b = d[a + 1 & 15]; + g = b + (h & i ^ k & (h ^ i)) + (h >>> 2 ^ h >>> 13 ^ h >>> 22 ^ h << 30 ^ h << 19 ^ h << 10) | 0 + } + e[0] = e[0] + g | 0; + } +}; +var ax1 = [-1862726214, -1544935945, -1650904951, -1523200565, 1783959997, -1422527763, -1915825893, 67249414]; +var ax2 = ax1; +for (var aix = 0; aix < 200; aix++) ax1 = (new sjcl.hash.sha256(undefined)).update(ax1, undefined).finalize(); +eval("for (var aix = 0; aix < 200; aix++) ax2 = (new sjcl.hash.sha256(undefined)).update(ax2, undefined).finalize();" + + "assertEq(ax2.toString(), ax1.toString());"); diff --git a/js/src/jit-test/tests/gc/elements-post-write-barrier.js b/js/src/jit-test/tests/gc/elements-post-write-barrier.js new file mode 100644 index 000000000..04249eb72 --- /dev/null +++ b/js/src/jit-test/tests/gc/elements-post-write-barrier.js @@ -0,0 +1,27 @@ +gczeal(12); + +var length = 10000; +var array = new Array(length); +array.fill(null); + +// Promote the array to the tenured heap, if it isn't already there. +minorgc(); + +for (var i = 0; i < length; i++) { + // Exercise that barrier with some fresh nursery object references! + array[i] = {}; +} + +minorgc(); + +for (var i = length; i > 0; i--) { + array[i - 1] = {}; +} + +minorgc(); + +for (var i = 0; i < length; i++) { + array[Math.floor(Math.random() * length)] = {}; +} + +gc(); diff --git a/js/src/jit-test/tests/gc/gcparam.js b/js/src/jit-test/tests/gc/gcparam.js new file mode 100644 index 000000000..c9320f72c --- /dev/null +++ b/js/src/jit-test/tests/gc/gcparam.js @@ -0,0 +1,45 @@ +function testGetParam(key) { + gcparam(key); +} + +function testChangeParam(key) { + let prev = gcparam(key); + let value = prev - 1; + gcparam(key, value); + assertEq(gcparam(key), value); + gcparam(key, prev); +} + +function testLargeParamValue(key) { + let prev = gcparam(key); + const value = 1000000; + gcparam(key, value); + assertEq(gcparam(key), value); + gcparam(key, prev); +} + +testGetParam("gcBytes"); +testGetParam("gcNumber"); +testGetParam("unusedChunks"); +testGetParam("totalChunks"); + +testChangeParam("maxBytes"); +testChangeParam("maxMallocBytes"); +testChangeParam("mode"); +testChangeParam("sliceTimeBudget"); +testChangeParam("markStackLimit"); +testChangeParam("highFrequencyTimeLimit"); +testChangeParam("highFrequencyLowLimit"); +testChangeParam("highFrequencyHighLimit"); +testChangeParam("highFrequencyHeapGrowthMax"); +testChangeParam("highFrequencyHeapGrowthMin"); +testChangeParam("lowFrequencyHeapGrowth"); +testChangeParam("dynamicHeapGrowth"); +testChangeParam("dynamicMarkSlice"); +testChangeParam("allocationThreshold"); +testChangeParam("minEmptyChunkCount"); +testChangeParam("maxEmptyChunkCount"); +testChangeParam("compactingEnabled"); + +testLargeParamValue("highFrequencyLowLimit"); +testLargeParamValue("highFrequencyHighLimit"); diff --git a/js/src/jit-test/tests/gc/gczeal-range.js b/js/src/jit-test/tests/gc/gczeal-range.js new file mode 100644 index 000000000..1589a54af --- /dev/null +++ b/js/src/jit-test/tests/gc/gczeal-range.js @@ -0,0 +1,5 @@ +try { + gczeal(123); +} catch(e) { + assertEq(e.toString().includes("out of range"), true); +} diff --git a/js/src/jit-test/tests/gc/incremental-01.js b/js/src/jit-test/tests/gc/incremental-01.js new file mode 100644 index 000000000..d4646c165 --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-01.js @@ -0,0 +1,31 @@ +var objs; + +function init() +{ + objs = new Object(); + var x = new Object(); + objs.root1 = x; + objs.root2 = new Object(); + x.ptr = new Object(); + x = null; + + /* + * Clears out the arena lists. Otherwise all the objects above + * would be considered to be created during the incremental GC. + */ + gc(); +} + +/* + * Use eval here so that the interpreter frames end up higher on the + * stack, which avoids them being seen later on by the conservative + * scanner. + */ +eval("init()"); + +gcslice(0); // Start IGC, but don't mark anything. +selectforgc(objs.root2); +gcslice(1); +objs.root2.ptr = objs.root1.ptr; +objs.root1.ptr = null; +gcslice(); diff --git a/js/src/jit-test/tests/gc/incremental-02.js b/js/src/jit-test/tests/gc/incremental-02.js new file mode 100644 index 000000000..a2a2c8de8 --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-02.js @@ -0,0 +1,30 @@ +var objs; + +function init() +{ + objs = new Object(); + var x = new Object(); + objs.root = x; + x.a = new Object(); + x.b = new Object(); + + /* + * Clears out the arena lists. Otherwise all the objects above + * would be considered to be created during the incremental GC. + */ + gc(); +} + +/* + * Use eval here so that the interpreter frames end up higher on the + * stack, which avoids them being seen later on by the conservative + * scanner. + */ +eval("init()"); + +gcslice(0); // Start IGC, but don't mark anything. +selectforgc(objs.root); +gcslice(1); +delete objs.root.b; +delete objs.root.a; +gcslice(); diff --git a/js/src/jit-test/tests/gc/incremental-AccessorShape-barrier.js b/js/src/jit-test/tests/gc/incremental-AccessorShape-barrier.js new file mode 100644 index 000000000..0055e2c51 --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-AccessorShape-barrier.js @@ -0,0 +1,18 @@ +gczeal(0); +gc(); + +var o = {}; +function foo() { + var i = 0; + startgc(0); + Object.defineProperty(o, 'foo', {configurable: true, get: function g() { return i; }, + set: function s() { return i; }}); + Object.defineProperty(o, 'foo', {configurable: true, get: function g() { return i; }, + set: function s() { return i; }}); + Object.defineProperty(o, 'foo', {configurable: true, get: function g() { return i; }, + set: function s() { return i; }}); + Object.defineProperty(o, 'foo', {configurable: true, get: function g() { return i; }, + set: function s() { return i; }}); + abortgc(); +} +foo(); diff --git a/js/src/jit-test/tests/gc/incremental-abort.js b/js/src/jit-test/tests/gc/incremental-abort.js new file mode 100644 index 000000000..db42c7051 --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-abort.js @@ -0,0 +1,54 @@ +// Test aborting an incremental GC in all possible states + +if (!("gcstate" in this && "gczeal" in this && "abortgc" in this)) + quit(); + +gczeal(0); +gc(); + +function testAbort(zoneCount, objectCount, sliceCount, abortState) +{ + // Allocate objectCount objects in zoneCount zones and run a incremental + // shrinking GC. + + var zones = []; + for (var i = 0; i < zoneCount; i++) { + var zone = newGlobal(); + evaluate("var objects; " + + "function makeObjectGraph(objectCount) { " + + " objects = []; " + + " for (var i = 0; i < objectCount; i++) " + + " objects.push({i: i}); " + + "}", + { global: zone }); + zone.makeObjectGraph(objectCount); + zones.push(zone); + } + + var didAbort = false; + startgc(sliceCount, "shrinking"); + while (gcstate() !== "NotActive") { + var state = gcstate(); + if (state == abortState) { + abortgc(); + didAbort = true; + break; + } + + gcslice(sliceCount); + } + + assertEq(gcstate(), "NotActive"); + if (abortState) + assertEq(didAbort, true); + + return zones; +} + +gczeal(0); +testAbort(10, 10000, 10000); +testAbort(10, 10000, 10000, "Mark"); +testAbort(10, 10000, 10000, "Sweep"); +testAbort(10, 10000, 10000, "Compact"); +// Note: we do not yield automatically before Finalize or Decommit, as they yield internally. +// Thus, we may not witness an incremental state in this phase and cannot test it explicitly. diff --git a/js/src/jit-test/tests/gc/incremental-compacting.js b/js/src/jit-test/tests/gc/incremental-compacting.js new file mode 100644 index 000000000..25f770ae6 --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-compacting.js @@ -0,0 +1,44 @@ +// Exercise incremental compacting GC
+// Run with MOZ_GCTIMER to see the timings
+
+if (!("gcstate" in this && "gczeal" in this))
+ quit();
+
+gczeal(0);
+
+function testCompacting(zoneCount, objectCount, sliceCount)
+{
+ // Allocate objectCount objects in zoneCount zones
+ // On linux64 debug builds we will move them all
+ // Run compacting GC with multiple slices
+
+ var zones = [];
+ for (var i = 0; i < zoneCount; i++) {
+ var zone = newGlobal();
+ evaluate("var objects; " +
+ "function makeObjectGraph(objectCount) { " +
+ " objects = []; " +
+ " for (var i = 0; i < objectCount; i++) " +
+ " objects.push({ serial: i }); " +
+ "}",
+ { global: zone });
+ zone.makeObjectGraph(objectCount);
+ zones.push(zone);
+ }
+
+ // Finish any alloc-triggered incremental GC
+ if (gcstate() !== "NotActive")
+ gc();
+
+ startgc(sliceCount, "shrinking");
+ while (gcstate() !== "NotActive") {
+ gcslice(sliceCount);
+ }
+
+ return zones;
+}
+
+testCompacting(1, 100000, 100000);
+testCompacting(2, 100000, 100000);
+testCompacting(4, 50000, 100000);
+testCompacting(2, 100000, 50000);
diff --git a/js/src/jit-test/tests/gc/incremental-state.js b/js/src/jit-test/tests/gc/incremental-state.js new file mode 100644 index 000000000..0d6566d0e --- /dev/null +++ b/js/src/jit-test/tests/gc/incremental-state.js @@ -0,0 +1,63 @@ +// Test expected state changes during collection. +if (!("gcstate" in this)) + quit(); + +gczeal(0); + +// Non-incremental GC. +gc(); +assertEq(gcstate(), "NotActive"); + +// Incremental GC in minimal slice. Note that finalization always uses zero- +// sized slices while background finalization is on-going, so we need to loop. +gcslice(1000000); +while (gcstate() == "Finalize") { gcslice(1); } +while (gcstate() == "Decommit") { gcslice(1); } +assertEq(gcstate(), "NotActive"); + +// Incremental GC in multiple slices: if marking takes more than one slice, +// we yield before we start sweeping. +gczeal(0); +gcslice(1); +assertEq(gcstate(), "Mark"); +gcslice(1000000); +assertEq(gcstate(), "Mark"); +gcslice(1000000); +while (gcstate() == "Finalize") { gcslice(1); } +while (gcstate() == "Decommit") { gcslice(1); } +assertEq(gcstate(), "NotActive"); + +// Zeal mode 8: Incremental GC in two main slices: +// 1) mark roots +// 2) mark and sweep +// *) finalize. +gczeal(8, 0); +gcslice(1); +assertEq(gcstate(), "Mark"); +gcslice(1); +while (gcstate() == "Finalize") { gcslice(1); } +while (gcstate() == "Decommit") { gcslice(1); } +assertEq(gcstate(), "NotActive"); + +// Zeal mode 9: Incremental GC in two main slices: +// 1) mark roots and marking +// 2) new marking and sweeping +// *) finalize. +gczeal(9, 0); +gcslice(1); +assertEq(gcstate(), "Mark"); +gcslice(1); +while (gcstate() == "Finalize") { gcslice(1); } +while (gcstate() == "Decommit") { gcslice(1); } +assertEq(gcstate(), "NotActive"); + +// Zeal mode 10: Incremental GC in multiple slices (always yeilds before +// sweeping). This test uses long slices to prove that this zeal mode yields +// in sweeping, where normal IGC (above) does not. +gczeal(10, 0); +gcslice(1000000); +assertEq(gcstate(), "Sweep"); +gcslice(1000000); +while (gcstate() == "Finalize") { gcslice(1); } +while (gcstate() == "Decommit") { gcslice(1); } +assertEq(gcstate(), "NotActive"); diff --git a/js/src/jit-test/tests/gc/jsscript-mark-children.js b/js/src/jit-test/tests/gc/jsscript-mark-children.js new file mode 100644 index 000000000..c74a19c0f --- /dev/null +++ b/js/src/jit-test/tests/gc/jsscript-mark-children.js @@ -0,0 +1,24 @@ +// Bug 758509 changed things so that a JSScript is partially initialized when +// it is created, which is prior to bytecode generation; full initialization +// only occurs after bytecode generation. This means that +// JSScript::markChildren() must deal with partially-initialized JSScripts. +// This test forces that to happen, because each let block allocates a +// StaticBlockObject. All that should happen is that we don't crash. + +let t = 0; +gczeal(2,1); +eval("\ +let x0 = 3, y = 4;\ +{ let x = x0+0, y = 12; t += (x + y); } \ +{ let x = x0+1, y = 12; t += (x + y); } \ +{ let x = x0+2, y = 12; t += (x + y); } \ +{ let x = x0+3, y = 12; t += (x + y); } \ +{ let x = x0+4, y = 12; t += (x + y); } \ +{ let x = x0+5, y = 12; t += (x + y); } \ +{ let x = x0+6, y = 12; t += (x + y); } \ +{ let x = x0+7, y = 12; t += (x + y); } \ +{ let x = x0+8, y = 12; t += (x + y); } \ +{ let x = x0+9, y = 12; t += (x + y); } \ +t += (x0 + y);\ +assertEq(t, 202);\ +"); diff --git a/js/src/jit-test/tests/gc/multi-01.js b/js/src/jit-test/tests/gc/multi-01.js new file mode 100644 index 000000000..90a3ae419 --- /dev/null +++ b/js/src/jit-test/tests/gc/multi-01.js @@ -0,0 +1,9 @@ +/* Make sure we don't collect the atoms compartment unless every compartment is marked. */ + +var g = newGlobal(); +g.eval("var x = 'some-atom';"); + +schedulegc(this); +schedulegc('atoms'); +gc('zone'); +print(g.x); diff --git a/js/src/jit-test/tests/gc/multi-02.js b/js/src/jit-test/tests/gc/multi-02.js new file mode 100644 index 000000000..56cae4557 --- /dev/null +++ b/js/src/jit-test/tests/gc/multi-02.js @@ -0,0 +1,10 @@ +/* Exercise the path where we want to collect a new compartment in the middle of incremental GC. */ + +var g1 = newGlobal(); +var g2 = newGlobal(); + +schedulegc(g1); +gcslice(0); // Start IGC, but don't mark anything. +schedulegc(g2); +gcslice(1); +gcslice(); diff --git a/js/src/jit-test/tests/gc/multi-03.js b/js/src/jit-test/tests/gc/multi-03.js new file mode 100644 index 000000000..fd9bd0830 --- /dev/null +++ b/js/src/jit-test/tests/gc/multi-03.js @@ -0,0 +1,11 @@ +/* Exercise the path where we want to collect a new compartment in the middle of incremental GC. */ + +var g1 = newGlobal(); +var g2 = newGlobal(); + +schedulegc(g1); +schedulegc(g2); +gcslice(0); // Start IGC, but don't mark anything. +schedulegc(g1); +gcslice(1); +gcslice(); diff --git a/js/src/jit-test/tests/gc/oomInArrayProtoTest.js b/js/src/jit-test/tests/gc/oomInArrayProtoTest.js new file mode 100644 index 000000000..f52846859 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInArrayProtoTest.js @@ -0,0 +1,23 @@ +if (!('oomTest' in this)) + quit(); + +function arrayProtoOutOfRange() { + function f(obj) { + return typeof obj[15]; + } + + function test() { + var a = [1, 2]; + a.__proto__ = {15: 1337}; + var b = [1, 2, 3, 4]; + + for (var i = 0; i < 200; i++) { + var r = f(i % 2 ? a : b); + assertEq(r, i % 2 ? "number" : "undefined"); + } + } + + test(); +} + +oomTest(arrayProtoOutOfRange); diff --git a/js/src/jit-test/tests/gc/oomInByteSize.js b/js/src/jit-test/tests/gc/oomInByteSize.js new file mode 100644 index 000000000..51c856e47 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInByteSize.js @@ -0,0 +1,19 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => byteSize({})); +oomTest(() => byteSize({ w: 1, x: 2, y: 3 })); +oomTest(() => byteSize({ w:1, x:2, y:3, z:4, a:6, 0:0, 1:1, 2:2 })); +oomTest(() => byteSize([1, 2, 3])); +oomTest(() => byteSize(function () {})); + +function f1() { + return 42; +} +oomTest(() => byteSizeOfScript(f1)); + +oomTest(() => byteSize("1234567")); +oomTest(() => byteSize("千早ぶる神代")); + +let s = Symbol(); +oomTest(() => byteSize(s)); diff --git a/js/src/jit-test/tests/gc/oomInDebugger.js b/js/src/jit-test/tests/gc/oomInDebugger.js new file mode 100644 index 000000000..adf7f64a7 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInDebugger.js @@ -0,0 +1,5 @@ +if (!('oomTest' in this)) + quit(); + +var g = newGlobal(); +oomTest(() => Debugger(g)); diff --git a/js/src/jit-test/tests/gc/oomInDtoa.js b/js/src/jit-test/tests/gc/oomInDtoa.js new file mode 100644 index 000000000..f006d36b0 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInDtoa.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(function() 1e300) diff --git a/js/src/jit-test/tests/gc/oomInExceptionHandlerBailout.js b/js/src/jit-test/tests/gc/oomInExceptionHandlerBailout.js new file mode 100644 index 000000000..fd77c00c6 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInExceptionHandlerBailout.js @@ -0,0 +1,16 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + let x = 0; + try { + for (let i = 0; i < 100; i++) { + if (i == 99) + throw "foo"; + x += i; + } + } catch (e) { + x = 0; + } + return x; +}); diff --git a/js/src/jit-test/tests/gc/oomInFindPath.js b/js/src/jit-test/tests/gc/oomInFindPath.js new file mode 100644 index 000000000..5495791b9 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInFindPath.js @@ -0,0 +1,19 @@ +if (!('oomTest' in this)) + quit(); + +var o = { w: { x: { y: { z: {} } } } }; +oomTest(() => findPath(o, o.w.x.y.z)); + +var a = [ , o ]; +oomTest(() => findPath(a, o)); + +function C() {} +C.prototype.obj = {}; +var c = new C; + +oomTest(() => findPath(c, c.obj)); + +function f(x) { return function g(y) { return x+y; }; } +var o = {} +var gc = f(o); +oomTest(() => findPath(gc, o)); diff --git a/js/src/jit-test/tests/gc/oomInFormatStackDump.js b/js/src/jit-test/tests/gc/oomInFormatStackDump.js new file mode 100644 index 000000000..94a398b02 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInFormatStackDump.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => getBacktrace({args: true, locals: true, thisprops: true})); diff --git a/js/src/jit-test/tests/gc/oomInGetJumpLabelForBranch.js b/js/src/jit-test/tests/gc/oomInGetJumpLabelForBranch.js new file mode 100644 index 000000000..e5df3de08 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInGetJumpLabelForBranch.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => getBacktrace({thisprops: gc() && delete addDebuggee.enabled})); diff --git a/js/src/jit-test/tests/gc/oomInNewGlobal.js b/js/src/jit-test/tests/gc/oomInNewGlobal.js new file mode 100644 index 000000000..443c3c8e0 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInNewGlobal.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(newGlobal); diff --git a/js/src/jit-test/tests/gc/oomInOffTheadCompile.js b/js/src/jit-test/tests/gc/oomInOffTheadCompile.js new file mode 100644 index 000000000..1ad79fadb --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInOffTheadCompile.js @@ -0,0 +1,15 @@ +if (!('oomTest' in this) || helperThreadCount() === 0) + quit(); + +oomTest(() => { + offThreadCompileScript( + ` + function f(x) { + if (x == 0) + return "foobar"; + return 1 + f(x - 1); + } + f(5); + `); + runOffThreadScript(); +}); diff --git a/js/src/jit-test/tests/gc/oomInOffTheadCompile2.js b/js/src/jit-test/tests/gc/oomInOffTheadCompile2.js new file mode 100644 index 000000000..1091930a5 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInOffTheadCompile2.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this) || helperThreadCount() === 0) + quit(); + +oomTest(() => { + offThreadCompileScript("function a(x) {"); + runOffThreadScript(); +}); diff --git a/js/src/jit-test/tests/gc/oomInOffTheadCompile3.js b/js/src/jit-test/tests/gc/oomInOffTheadCompile3.js new file mode 100644 index 000000000..38dc523b6 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInOffTheadCompile3.js @@ -0,0 +1,17 @@ +if (!('oomTest' in this) || helperThreadCount() === 0) + quit(); + +oomTest(() => { + offThreadCompileScript(` + function f(x) { + class of extends ("ABCDEFGHIJK") { + test() { return true; }; + static get() {}; + static get() {}; + } + return 1 + f(x - 1); + } + return g("try{}catch(e){}", n); + `); + runOffThreadScript(); +}); diff --git a/js/src/jit-test/tests/gc/oomInParseAsmJS.js b/js/src/jit-test/tests/gc/oomInParseAsmJS.js new file mode 100644 index 000000000..b5279a26a --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInParseAsmJS.js @@ -0,0 +1,17 @@ +if (!('oomTest' in this)) + quit(); + +function parseAsmJS() { + eval(`function m(stdlib) + { + "use asm"; + var abs = stdlib.Math.abs; + function f(d) + { + d = +d; + return (~~(5.0 - +abs(d)))|0; + } + return f; + }`); +} +oomTest(parseAsmJS); diff --git a/js/src/jit-test/tests/gc/oomInParseFunction.js b/js/src/jit-test/tests/gc/oomInParseFunction.js new file mode 100644 index 000000000..9946bc2d0 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInParseFunction.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => eval("function f() {}")); diff --git a/js/src/jit-test/tests/gc/oomInRegExp.js b/js/src/jit-test/tests/gc/oomInRegExp.js new file mode 100644 index 000000000..a7f36b9d0 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInRegExp.js @@ -0,0 +1,6 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => assertEq("foobar\xff5baz\u1200".search(/bar\u0178\d/i), 3)); +oomTest(() => assertEq((/(?!(?!(?!6)[\Wc]))/i).test(), false)); +oomTest(() => assertEq((/bar\u0178\d/i).exec("foobar\xff5baz\u1200") != null, true)); diff --git a/js/src/jit-test/tests/gc/oomInRegExpAlternativeGeneration.js b/js/src/jit-test/tests/gc/oomInRegExpAlternativeGeneration.js new file mode 100644 index 000000000..97d66191b --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInRegExpAlternativeGeneration.js @@ -0,0 +1,15 @@ +// |jit-test| allow-oom; allow-unhandlable-oom +// Bug 1234402 +// Unhandlable OOM in AlternativeGeneration::AlternativeGeneration. + +if (typeof oomAfterAllocations == "function" && helperThreadCount() > 0) { + offThreadCompileScript(` +[null, "", ""].forEach(function(locales) { +try { +Intl.NumberFormat(locales) +} catch (e) {} +oomAfterAllocations(100); +}) +`); + runOffThreadScript(); +} diff --git a/js/src/jit-test/tests/gc/oomInWeakMap.js b/js/src/jit-test/tests/gc/oomInWeakMap.js new file mode 100644 index 000000000..157d72890 --- /dev/null +++ b/js/src/jit-test/tests/gc/oomInWeakMap.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(function () { + eval(`var wm = new WeakMap(); + wm.set({}, 'FOO').get(false);`); +}); diff --git a/js/src/jit-test/tests/gc/weak-marking-01.js b/js/src/jit-test/tests/gc/weak-marking-01.js new file mode 100644 index 000000000..7a100f6e1 --- /dev/null +++ b/js/src/jit-test/tests/gc/weak-marking-01.js @@ -0,0 +1,193 @@ +// These tests will be using object literals as keys, and we want some of them +// to be dead after being inserted into a WeakMap. That means we must wrap +// everything in functions because it seems like the toplevel script hangs onto +// its object literals. + +// All reachable keys should be found, and the rest should be swept. +function basicSweeping() { + var wm1 = new WeakMap(); + wm1.set({'name': 'obj1'}, {'name': 'val1'}); + var hold = {'name': 'obj2'}; + wm1.set(hold, {'name': 'val2'}); + wm1.set({'name': 'obj3'}, {'name': 'val3'}); + + startgc(100000, 'shrinking'); + gcslice(); + + assertEq(wm1.get(hold).name, 'val2'); + assertEq(nondeterministicGetWeakMapKeys(wm1).length, 1); +} + +basicSweeping(); + +// Keep values alive even when they are only referenced by (live) WeakMap values. +function weakGraph() { + var wm1 = new WeakMap(); + var obj1 = {'name': 'obj1'}; + var obj2 = {'name': 'obj2'}; + var obj3 = {'name': 'obj3'}; + var obj4 = {'name': 'obj4'}; + var clear = {'name': ''}; // Make the interpreter forget about the last obj created + + wm1.set(obj2, obj3); + wm1.set(obj3, obj1); + wm1.set(obj4, obj1); // This edge will be cleared + obj1 = obj3 = obj4 = undefined; + + startgc(100000, 'shrinking'); + gcslice(); + + assertEq(obj2.name, "obj2"); + assertEq(wm1.get(obj2).name, "obj3"); + assertEq(wm1.get(wm1.get(obj2)).name, "obj1"); + print(nondeterministicGetWeakMapKeys(wm1).map(o => o.name).join(",")); + assertEq(nondeterministicGetWeakMapKeys(wm1).length, 2); +} + +weakGraph(); + +// ...but the weakmap itself has to stay alive, too. +function deadWeakMap() { + var wm1 = new WeakMap(); + var obj1 = makeFinalizeObserver(); + var obj2 = {'name': 'obj2'}; + var obj3 = {'name': 'obj3'}; + var obj4 = {'name': 'obj4'}; + var clear = {'name': ''}; // Make the interpreter forget about the last obj created + + wm1.set(obj2, obj3); + wm1.set(obj3, obj1); + wm1.set(obj4, obj1); // This edge will be cleared + var initialCount = finalizeCount(); + obj1 = obj3 = obj4 = undefined; + wm1 = undefined; + + startgc(100000, 'shrinking'); + gcslice(); + + assertEq(obj2.name, "obj2"); + assertEq(finalizeCount(), initialCount + 1); +} + +deadWeakMap(); + +// WeakMaps do not strongly reference their keys or values. (WeakMaps hold a +// collection of (strong) references to *edges* from keys to values. If the +// WeakMap is not live, then its edges are of course not live either. An edge +// holds neither its key nor its value live; it just holds a strong ref from +// the key to the value. So if the key is live, the value is live too, but the +// edge itself has no references to anything.) +function deadKeys() { + var wm1 = new WeakMap(); + var obj1 = makeFinalizeObserver(); + var obj2 = {'name': 'obj2'}; + var obj3 = makeFinalizeObserver(); + var clear = {}; // Make the interpreter forget about the last obj created + + wm1.set(obj1, obj1); + wm1.set(obj3, obj2); + obj1 = obj3 = undefined; + var initialCount = finalizeCount(); + + startgc(100000, 'shrinking'); + gcslice(); + + assertEq(finalizeCount(), initialCount + 2); + assertEq(nondeterministicGetWeakMapKeys(wm1).length, 0); +} + +deadKeys(); + +// The weakKeys table has to grow if it encounters enough new unmarked weakmap +// keys. Trigger this to happen during weakmap marking. +// +// There's some trickiness involved in getting it to test the right thing, +// because if a key is marked before the weakmap, then it won't get entered +// into the weakKeys table. This chains through multiple weakmap layers to +// ensure that the objects can't get marked before the weakmaps. +function weakKeysRealloc() { + var wm1 = new WeakMap; + var wm2 = new WeakMap; + var wm3 = new WeakMap; + var obj1 = {'name': 'obj1'}; + var obj2 = {'name': 'obj2'}; + wm1.set(obj1, wm2); + wm2.set(obj2, wm3); + for (var i = 0; i < 10000; i++) { + wm3.set(Object.create(null), wm2); + } + wm3.set(Object.create(null), makeFinalizeObserver()); + wm2 = undefined; + wm3 = undefined; + obj2 = undefined; + + var initialCount = finalizeCount(); + startgc(100000, 'shrinking'); + gcslice(); + assertEq(finalizeCount(), initialCount + 1); +} + +weakKeysRealloc(); + +// The weakKeys table is populated during regular marking. When a key is later +// deleted, both it and its delegate should be removed from weakKeys. +// Otherwise, it will hold its value live if it gets marked, and our table +// traversals will include non-keys, etc. +function deletedKeys() { + var wm = new WeakMap; + var g = newGlobal(); + + for (var i = 0; i < 1000; i++) + wm.set(g.Object.create(null), i); + + startgc(100, 'shrinking'); + for (var key of nondeterministicGetWeakMapKeys(wm)) { + if (wm.get(key) % 2) + wm.delete(key); + } + + gc(); +} + +deletedKeys(); + +// Test adding keys during incremental GC. +function incrementalAdds() { + var initialCount = finalizeCount(); + + var wm1 = new WeakMap; + var wm2 = new WeakMap; + var wm3 = new WeakMap; + var obj1 = {'name': 'obj1'}; + var obj2 = {'name': 'obj2'}; + wm1.set(obj1, wm2); + wm2.set(obj2, wm3); + for (var i = 0; i < 10000; i++) { + wm3.set(Object.create(null), wm2); + } + wm3.set(Object.create(null), makeFinalizeObserver()); + obj2 = undefined; + + var obj3 = []; + startgc(100, 'shrinking'); + var M = 10; + var N = 800; + for (var j = 0; j < M; j++) { + for (var i = 0; i < N; i++) + wm3.set(Object.create(null), makeFinalizeObserver()); // Should be swept + for (var i = 0; i < N; i++) { + obj3.push({'name': 'obj3'}); + wm1.set(obj3[obj3.length - 1], makeFinalizeObserver()); // Should not be swept + } + gcslice(); + } + + wm2 = undefined; + wm3 = undefined; + + gc(); + print("initialCount = " + initialCount); + assertEq(finalizeCount(), initialCount + 1 + M * N); +} + +incrementalAdds(); diff --git a/js/src/jit-test/tests/gc/weak-marking-02.js b/js/src/jit-test/tests/gc/weak-marking-02.js new file mode 100644 index 000000000..c3d9a0516 --- /dev/null +++ b/js/src/jit-test/tests/gc/weak-marking-02.js @@ -0,0 +1,128 @@ +// These tests will be using object literals as keys, and we want some of them +// to be dead after being inserted into a WeakMap. That means we must wrap +// everything in functions because it seems like the toplevel script hangs onto +// its object literals. + +// Cross-compartment WeakMap keys work by storing a cross-compartment wrapper +// in the WeakMap, and the actual "delegate" object in the target compartment +// is the thing whose liveness is checked. + +var g2 = newGlobal(); +g2.eval('function genObj(name) { return {"name": name} }'); + +function basicSweeping() { + var wm1 = new WeakMap(); + wm1.set({'name': 'obj1'}, {'name': 'val1'}); + var hold = g2.genObj('obj2'); + wm1.set(hold, {'name': 'val2'}); + wm1.set({'name': 'obj3'}, {'name': 'val3'}); + var obj4 = g2.genObj('obj4'); + wm1.set(obj4, {'name': 'val3'}); + obj4 = undefined; + + startgc(100000, 'shrinking'); + gcslice(); + assertEq(wm1.get(hold).name, 'val2'); + assertEq(nondeterministicGetWeakMapKeys(wm1).length, 1); +} + +basicSweeping(); + +// Same, but behind an additional WM layer, to avoid ordering problems (not +// that I've checked that basicSweeping even has any problems.) + +function basicSweeping2() { + var wm1 = new WeakMap(); + wm1.set({'name': 'obj1'}, {'name': 'val1'}); + var hold = g2.genObj('obj2'); + wm1.set(hold, {'name': 'val2'}); + wm1.set({'name': 'obj3'}, {'name': 'val3'}); + var obj4 = g2.genObj('obj4'); + wm1.set(obj4, {'name': 'val3'}); + obj4 = undefined; + + var base1 = {'name': 'base1'}; + var base2 = {'name': 'base2'}; + var wm_base1 = new WeakMap(); + var wm_base2 = new WeakMap(); + wm_base1.set(base1, wm_base2); + wm_base2.set(base2, wm1); + wm1 = wm_base2 = undefined; + + startgc(100000, 'shrinking'); + gcslice(); + + assertEq(nondeterministicGetWeakMapKeys(wm_base1).length, 1); + wm_base2 = wm_base1.get(base1); + assertEq(nondeterministicGetWeakMapKeys(wm_base2).length, 1); + assertEq(nondeterministicGetWeakMapKeys(wm_base1)[0], base1); + assertEq(nondeterministicGetWeakMapKeys(wm_base2)[0], base2); + wm_base2 = wm_base1.get(base1); + wm1 = wm_base2.get(base2); + assertEq(wm1.get(hold).name, 'val2'); + assertEq(nondeterministicGetWeakMapKeys(wm1).length, 1); +} + +basicSweeping2(); + +// Scatter the weakmap, the keys, and the values among different compartments. + +function tripleZoneMarking() { + var g1 = newGlobal(); + var g2 = newGlobal(); + var g3 = newGlobal(); + + var wm = g1.eval("new WeakMap()"); + var key = g2.eval("({'name': 'obj1'})"); + var value = g3.eval("({'name': 'val1'})"); + g1 = g2 = g3 = undefined; + wm.set(key, value); + + // Make all of it only reachable via a weakmap in the main test compartment, + // so that all of this happens during weak marking mode. Use the weakmap as + // its own key, so we know that the weakmap will get traced before the key + // and therefore will populate the weakKeys table and all of that jazz. + var base_wm = new WeakMap(); + base_wm.set(base_wm, [ wm, key ]); + + wm = key = value = undefined; + + startgc(100000, 'shrinking'); + gcslice(); + + var keys = nondeterministicGetWeakMapKeys(base_wm); + assertEq(keys.length, 1); + var [ wm, key ] = base_wm.get(keys[0]); + assertEq(key.name, "obj1"); + value = wm.get(key); + assertEq(value.name, "val1"); +} + +tripleZoneMarking(); + +function enbugger() { + var g = newGlobal(); + var dbg = new Debugger; + g.eval("function debuggee_f() { return 1; }"); + g.eval("function debuggee_g() { return 1; }"); + dbg.addDebuggee(g); + var [ s ] = dbg.findScripts({global: g}).filter(s => s.displayName == "debuggee_f"); + var [ s2 ] = dbg.findScripts({global: g}).filter(s => s.displayName == "debuggee_g"); + g.eval("debuggee_f = null"); + gc(); + dbg.removeAllDebuggees(); + gc(); + assertEq(s.displayName, "debuggee_f"); + + var wm = new WeakMap; + var obj = Object.create(null); + var obj2 = Object.create(null); + wm.set(obj, s); + wm.set(obj2, obj); + wm.set(s2, obj2); + s = s2 = obj = obj2 = null; + + gc(); +} + +enbugger(); |