Bug 1322420 - Trigger a read barrier when creating new reference to a compartment's lazy functions r=sfink a=dveditz
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 19 Dec 2016 17:02:00 +0000
changeset 359186 b4c638e2f6e5454e648630aed3c19b81857b62bf
parent 359185 8ab2c27f4cc096922e6db9bc4cc083c4f3dac4f7
child 359187 740621a15dc4813acc4b13eed9f9233bf9cdffb4
push id1324
push usermtabara@mozilla.com
push dateMon, 16 Jan 2017 13:07:44 +0000
treeherdermozilla-release@a01c49833940 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, dveditz
bugs1322420
milestone51.0
Bug 1322420 - Trigger a read barrier when creating new reference to a compartment's lazy functions r=sfink a=dveditz
js/src/jit-test/tests/gc/bug-1322420.js
js/src/jscompartment.cpp
new file mode 100644
--- /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({});
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -988,16 +988,25 @@ AddLazyFunctionsForCompartment(JSContext
         // are about to be finalized. GC things referenced by objects that are
         // about to be finalized (e.g., in slots) may already be freed.
         if (gc::IsAboutToBeFinalizedUnbarriered(&fun) ||
             fun->compartment() != cx->compartment())
         {
             continue;
         }
 
+        // This creates a new reference to an object that an ongoing incremental
+        // GC may find to be unreachable. Treat as if we're reading a weak
+        // reference and trigger the read barrier.
+        if (cx->zone()->needsIncrementalBarrier())
+            fun->readBarrier(fun);
+
+        // TODO: The above checks should be rolled into the cell iterator (see
+        // bug 1322971).
+
         if (fun->isInterpretedLazy()) {
             LazyScript* lazy = fun->lazyScriptOrNull();
             if (lazy && lazy->sourceObject() && !lazy->hasUncompiledEnclosingScript()) {
                 if (!lazyFunctions.append(fun))
                     return false;
             }
         }
     }