summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc/incremental-state.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/gc/incremental-state.js')
-rw-r--r--js/src/jit-test/tests/gc/incremental-state.js96
1 files changed, 96 insertions, 0 deletions
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 0000000000..f20b722234
--- /dev/null
+++ b/js/src/jit-test/tests/gc/incremental-state.js
@@ -0,0 +1,96 @@
+// |jit-test| skip-if: !hasFunction["gczeal"]
+
+function assert(x) {
+ assertEq(true, x);
+}
+
+function waitForState(state) {
+ while (gcstate() !== state && gcstate() !== "NotActive") {
+ gcslice(100);
+ }
+}
+
+// Test expected state changes during collection.
+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);
+assert(gcstate() !== "Mark");
+finishgc();
+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);
+waitForState("Mark");
+assertEq(gcstate(), "Mark");
+gcslice(1000000);
+assertEq(gcstate(), "Mark");
+gcslice(1000000);
+assert(gcstate() !== "Mark");
+finishgc();
+
+// Zeal mode 6: Incremental GC in two slices:
+// 1) prepare
+// 2) mark roots, mark and sweep
+gczeal(6, 0);
+gcslice(1);
+assertEq(gcstate(), "Prepare");
+gcslice(1);
+assertEq(gcstate(), "NotActive");
+
+// Zeal mode 8: Incremental GC in two slices:
+// 1) prepare and mark roots
+// 2) mark and sweep
+gczeal(8, 0);
+gcslice(1);
+assertEq(gcstate(), "Mark");
+gcslice(1);
+assertEq(gcstate(), "NotActive");
+
+// Zeal mode 9: Incremental GC in two slices:
+// 1) prepare, mark roots and marking
+// 2) new marking and sweeping
+gczeal(9, 0);
+gcslice(1);
+assertEq(gcstate(), "Mark");
+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);
+while (gcstate() === "Prepare") {
+ gcslice(1000000);
+}
+assertEq(gcstate(), "Sweep");
+gcslice(1000000);
+assert(gcstate() !== "Sweep");
+finishgc();
+
+// Two-slice zeal modes that yield once during sweeping.
+for (let mode of [ 17, 19 ]) {
+ gczeal(mode, 0);
+ gcslice(1);
+ assertEq(gcstate(), "Sweep");
+ gcslice(1);
+ assertEq(gcstate(), "NotActive");
+}
+
+// Two-slice zeal modes that yield per-zone during sweeping.
+const sweepingZealModes = [ 20, 21, 22, 23 ];
+for (let mode of sweepingZealModes) {
+ gczeal(mode, 0);
+ gcslice(1);
+ while (gcstate() === "Sweep")
+ gcslice(1);
+ assertEq(gcstate(), "NotActive");
+}