summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/gc/bug-1578462.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/gc/bug-1578462.js')
-rw-r--r--js/src/jit-test/tests/gc/bug-1578462.js59
1 files changed, 59 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/gc/bug-1578462.js b/js/src/jit-test/tests/gc/bug-1578462.js
new file mode 100644
index 0000000000..da3644511a
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1578462.js
@@ -0,0 +1,59 @@
+// |jit-test| skip-if: !hasFunction["gczeal"]
+
+// Check that incoming CCW edges are marked gray in a zone GC if the
+// source is gray.
+
+// Set up a new compartment with a gray object wrapper to this
+// compartment.
+function createOtherCompartment() {
+ let t = {};
+ addMarkObservers([t]);
+ let g = newGlobal({newCompartment: true});
+ g.t = t;
+ g.eval(`grayRoot().push(t);`);
+ g.t = null;
+ t = null;
+ return g;
+}
+
+function startGCMarking() {
+ startgc(1);
+ while (gcstate() === "Prepare") {
+ gcslice(1);
+ }
+}
+
+gczeal(0);
+
+let g = createOtherCompartment();
+
+// The target should be gray in a full GC...
+gc();
+assertEq(getMarks()[0], "gray");
+
+// and subsequently gray in a zone GC of only this compartment.
+gc(this);
+assertEq(getMarks()[0], "gray");
+
+// If a barrier marks the gray wrapper black after the start of the
+// GC, the target ends up black.
+schedulezone(this);
+startGCMarking()
+assertEq(getMarks()[0], "unmarked");
+g.eval(`grayRoot()`); // Barrier marks gray roots black.
+assertEq(getMarks()[0], "black");
+finishgc();
+
+// A full collection resets the wrapper to gray.
+gc();
+assertEq(getMarks()[0], "gray");
+
+// If a barrier marks the gray wrapper black after the target has
+// already been marked gray, the target ends up black.
+gczeal(25); // Yield during gray marking.
+schedulezone(this);
+startGCMarking();
+assertEq(getMarks()[0], "gray");
+g.eval(`grayRoot()`); // Barrier marks gray roots black.
+assertEq(getMarks()[0], "black");
+finishgc();