summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/gc')
-rw-r--r--js/src/jit-test/tests/gc/bug-1004457.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-1016016.js15
-rw-r--r--js/src/jit-test/tests/gc/bug-1017141.js25
-rw-r--r--js/src/jit-test/tests/gc/bug-1028863.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-1032206.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-1035371.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1039516.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-1053676.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1055219.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1070638.js20
-rw-r--r--js/src/jit-test/tests/gc/bug-1075546.js30
-rw-r--r--js/src/jit-test/tests/gc/bug-1104162.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1108007.js24
-rw-r--r--js/src/jit-test/tests/gc/bug-1108836.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1109913.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1109922.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-1123648.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1124563.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1124653.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1136597.js24
-rw-r--r--js/src/jit-test/tests/gc/bug-1137341.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-1138390.js28
-rw-r--r--js/src/jit-test/tests/gc/bug-1143706.js2
-rw-r--r--js/src/jit-test/tests/gc/bug-1144738.js32
-rw-r--r--js/src/jit-test/tests/gc/bug-1146696.js21
-rw-r--r--js/src/jit-test/tests/gc/bug-1148383.js19
-rw-r--r--js/src/jit-test/tests/gc/bug-1155455.js17
-rw-r--r--js/src/jit-test/tests/gc/bug-1157577.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1161303.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1161968.js15
-rw-r--r--js/src/jit-test/tests/gc/bug-1165966.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1171909.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1175755.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1177778.js16
-rw-r--r--js/src/jit-test/tests/gc/bug-1188290.js21
-rw-r--r--js/src/jit-test/tests/gc/bug-1191576.js17
-rw-r--r--js/src/jit-test/tests/gc/bug-1196210.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-1206677.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1208994.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1209001.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1210607.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1214006.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1214781.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1214846.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1215363-1.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1215363-2.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1215363-3.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1215678.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1216607.js19
-rw-r--r--js/src/jit-test/tests/gc/bug-1218900-2.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-1218900.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1221359.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1221747.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1223021.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1224710.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-1226888.js19
-rw-r--r--js/src/jit-test/tests/gc/bug-1226896.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1231386.js19
-rw-r--r--js/src/jit-test/tests/gc/bug-1232386.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1234410.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1236473.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1237153.js2
-rw-r--r--js/src/jit-test/tests/gc/bug-1238548.js2
-rw-r--r--js/src/jit-test/tests/gc/bug-1238555.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1238575-2.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1238575.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1238582.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1240416.js2
-rw-r--r--js/src/jit-test/tests/gc/bug-1240503.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1240527.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-1241731.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1242812.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1245520.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1246593.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-1252103.js22
-rw-r--r--js/src/jit-test/tests/gc/bug-1252154.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-1252329.js34
-rw-r--r--js/src/jit-test/tests/gc/bug-1253124.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-1254108.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1258407.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1259306.js19
-rw-r--r--js/src/jit-test/tests/gc/bug-1259490.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1261329.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1263862.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1263871.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1263884.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1271110.js37
-rw-r--r--js/src/jit-test/tests/gc/bug-1276631.js17
-rw-r--r--js/src/jit-test/tests/gc/bug-1278832.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1280588.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-1280889.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-1282986.js17
-rw-r--r--js/src/jit-test/tests/gc/bug-1286244.js16
-rw-r--r--js/src/jit-test/tests/gc/bug-1287399.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1287869.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1292564.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1293127.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-1294241.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1298356.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1301377.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1301496.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-1303015.js13
-rw-r--r--js/src/jit-test/tests/gc/bug-1305220.js23
-rw-r--r--js/src/jit-test/tests/gc/bug-1308048.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1310589.js299
-rw-r--r--js/src/jit-test/tests/gc/bug-1311060.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-1313347.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-1315946.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-1321597.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-1322420.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-1324512.js13
-rw-r--r--js/src/jit-test/tests/gc/bug-1328251.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-1332773.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-1338383.js16
-rw-r--r--js/src/jit-test/tests/gc/bug-1357022.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-787703.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-820186.js297
-rw-r--r--js/src/jit-test/tests/gc/bug-821013.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-821551.js16
-rw-r--r--js/src/jit-test/tests/gc/bug-824321.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-825326.js18
-rw-r--r--js/src/jit-test/tests/gc/bug-832103.js27
-rw-r--r--js/src/jit-test/tests/gc/bug-880816.js30
-rw-r--r--js/src/jit-test/tests/gc/bug-880886.js10
-rw-r--r--js/src/jit-test/tests/gc/bug-886551-1.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-886551-2.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-886560.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-886630.js112
-rw-r--r--js/src/jit-test/tests/gc/bug-889682-1.js13
-rw-r--r--js/src/jit-test/tests/gc/bug-889682-2.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-889682-3.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-891773.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-900405.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-906236.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-906241.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-906243.js12
-rw-r--r--js/src/jit-test/tests/gc/bug-912734.js43
-rw-r--r--js/src/jit-test/tests/gc/bug-912813.js7
-rw-r--r--js/src/jit-test/tests/gc/bug-913224.js1
-rw-r--r--js/src/jit-test/tests/gc/bug-913261.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-913715.js31
-rw-r--r--js/src/jit-test/tests/gc/bug-919536.js17
-rw-r--r--js/src/jit-test/tests/gc/bug-924690.js25
-rw-r--r--js/src/jit-test/tests/gc/bug-935022.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-939499.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-945275.js11
-rw-r--r--js/src/jit-test/tests/gc/bug-945280.js4
-rw-r--r--js/src/jit-test/tests/gc/bug-945285.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-948423.js23
-rw-r--r--js/src/jit-test/tests/gc/bug-950927.js31
-rw-r--r--js/src/jit-test/tests/gc/bug-952819.js3
-rw-r--r--js/src/jit-test/tests/gc/bug-956324.js28
-rw-r--r--js/src/jit-test/tests/gc/bug-957110.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-957114.js13
-rw-r--r--js/src/jit-test/tests/gc/bug-961741.js5
-rw-r--r--js/src/jit-test/tests/gc/bug-961877.js14
-rw-r--r--js/src/jit-test/tests/gc/bug-969012.js60
-rw-r--r--js/src/jit-test/tests/gc/bug-978353.js6
-rw-r--r--js/src/jit-test/tests/gc/bug-978802.js18
-rw-r--r--js/src/jit-test/tests/gc/bug-981289.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-981295.js9
-rw-r--r--js/src/jit-test/tests/gc/bug-985732.js84
-rw-r--r--js/src/jit-test/tests/gc/bug-986864.js8
-rw-r--r--js/src/jit-test/tests/gc/bug-993768.js13
-rw-r--r--js/src/jit-test/tests/gc/bug1116306.js8
-rw-r--r--js/src/jit-test/tests/gc/bug1191756.js19
-rw-r--r--js/src/jit-test/tests/gc/bug1246607.js16
-rw-r--r--js/src/jit-test/tests/gc/bug1282113.js6
-rw-r--r--js/src/jit-test/tests/gc/bug1283169.js4
-rw-r--r--js/src/jit-test/tests/gc/bug1285186.js6
-rw-r--r--js/src/jit-test/tests/gc/bug1285490.js4
-rw-r--r--js/src/jit-test/tests/gc/bug1287063.js4
-rw-r--r--js/src/jit-test/tests/gc/bug888463.js66
-rw-r--r--js/src/jit-test/tests/gc/elements-post-write-barrier.js27
-rw-r--r--js/src/jit-test/tests/gc/gcparam.js45
-rw-r--r--js/src/jit-test/tests/gc/gczeal-range.js5
-rw-r--r--js/src/jit-test/tests/gc/incremental-01.js31
-rw-r--r--js/src/jit-test/tests/gc/incremental-02.js30
-rw-r--r--js/src/jit-test/tests/gc/incremental-AccessorShape-barrier.js18
-rw-r--r--js/src/jit-test/tests/gc/incremental-abort.js54
-rw-r--r--js/src/jit-test/tests/gc/incremental-compacting.js44
-rw-r--r--js/src/jit-test/tests/gc/incremental-state.js63
-rw-r--r--js/src/jit-test/tests/gc/jsscript-mark-children.js24
-rw-r--r--js/src/jit-test/tests/gc/multi-01.js9
-rw-r--r--js/src/jit-test/tests/gc/multi-02.js10
-rw-r--r--js/src/jit-test/tests/gc/multi-03.js11
-rw-r--r--js/src/jit-test/tests/gc/oomInArrayProtoTest.js23
-rw-r--r--js/src/jit-test/tests/gc/oomInByteSize.js19
-rw-r--r--js/src/jit-test/tests/gc/oomInDebugger.js5
-rw-r--r--js/src/jit-test/tests/gc/oomInDtoa.js4
-rw-r--r--js/src/jit-test/tests/gc/oomInExceptionHandlerBailout.js16
-rw-r--r--js/src/jit-test/tests/gc/oomInFindPath.js19
-rw-r--r--js/src/jit-test/tests/gc/oomInFormatStackDump.js4
-rw-r--r--js/src/jit-test/tests/gc/oomInGetJumpLabelForBranch.js4
-rw-r--r--js/src/jit-test/tests/gc/oomInNewGlobal.js4
-rw-r--r--js/src/jit-test/tests/gc/oomInOffTheadCompile.js15
-rw-r--r--js/src/jit-test/tests/gc/oomInOffTheadCompile2.js7
-rw-r--r--js/src/jit-test/tests/gc/oomInOffTheadCompile3.js17
-rw-r--r--js/src/jit-test/tests/gc/oomInParseAsmJS.js17
-rw-r--r--js/src/jit-test/tests/gc/oomInParseFunction.js4
-rw-r--r--js/src/jit-test/tests/gc/oomInRegExp.js6
-rw-r--r--js/src/jit-test/tests/gc/oomInRegExpAlternativeGeneration.js15
-rw-r--r--js/src/jit-test/tests/gc/oomInWeakMap.js7
-rw-r--r--js/src/jit-test/tests/gc/weak-marking-01.js193
-rw-r--r--js/src/jit-test/tests/gc/weak-marking-02.js128
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();