Bug 1455608 - Allow js::TraceRuntime to operate if GC is suppressed r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 24 Apr 2018 09:32:14 +0100
changeset 471388 d736cc8113cf3b13f70e79ec5d7c0023c71cb654
parent 471387 86f3ef9d3d24805672d5715e79953742a8a82dc4
child 471389 628622df5bf4a7387f2b70fe422087151a172ff3
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1455608
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1455608 - Allow js::TraceRuntime to operate if GC is suppressed r=sfink
js/src/gc/RootMarking.cpp
js/src/jit-test/tests/gc/bug-1455608.js
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -242,16 +242,17 @@ PropertyDescriptor::trace(JSTracer* trc)
         TraceRoot(trc, &tmp, "Descriptor::set");
         setter = JS_DATA_TO_FUNC_PTR(JSSetterOp, tmp);
     }
 }
 
 void
 js::gc::GCRuntime::traceRuntimeForMajorGC(JSTracer* trc, AutoTraceSession& session)
 {
+    MOZ_ASSERT(!TlsContext.get()->suppressGC);
     MOZ_ASSERT_IF(atomsZone->isCollecting(), session.maybeLock.isSome());
 
     // FinishRoots will have asserted that every root that we do not expect
     // is gone, so we can simply skip traceRuntime here.
     if (rt->isBeingDestroyed())
         return;
 
     gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_ROOTS);
@@ -259,16 +260,18 @@ js::gc::GCRuntime::traceRuntimeForMajorG
         traceRuntimeAtoms(trc, session.lock());
     JSCompartment::traceIncomingCrossCompartmentEdgesForZoneGC(trc);
     traceRuntimeCommon(trc, MarkRuntime, session);
 }
 
 void
 js::gc::GCRuntime::traceRuntimeForMinorGC(JSTracer* trc, AutoTraceSession& session)
 {
+    MOZ_ASSERT(!TlsContext.get()->suppressGC);
+
     // Note that we *must* trace the runtime during the SHUTDOWN_GC's minor GC
     // despite having called FinishRoots already. This is because FinishRoots
     // does not clear the crossCompartmentWrapper map. It cannot do this
     // because Proxy's trace for CrossCompartmentWrappers asserts presence in
     // the map. And we can reach its trace function despite having finished the
     // roots via the edges stored by the pre-barrier verifier when we finish
     // the verifier for the last time.
     gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_ROOTS);
@@ -309,18 +312,16 @@ js::gc::GCRuntime::traceRuntimeAtoms(JST
     TraceWellKnownSymbols(trc);
     jit::JitRuntime::Trace(trc, lock);
 }
 
 void
 js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark,
                                       AutoTraceSession& session)
 {
-    MOZ_ASSERT(!TlsContext.get()->suppressGC);
-
     {
         gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_STACK);
 
         JSContext* cx = rt->mainContextFromOwnThread();
 
         // Trace active interpreter and JIT stack roots.
         TraceInterpreterActivations(cx, trc);
         jit::TraceJitActivations(cx, trc);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1455608.js
@@ -0,0 +1,25 @@
+// |jit-test| --wasm-gc
+
+var lfModule = new WebAssembly.Module(wasmTextToBinary(`
+    (module
+        (import "global" "func" (result i32))
+        (func (export "func_0") (result i32)
+         call 0 ;; calls the import, which is func #0
+        )
+    )
+`));
+processModule(lfModule, `
+  var dbg = new Debugger;
+  dbg.memory.takeCensus()
+`);
+function processModule(module, jscode) {
+    imports = {}
+    for (let descriptor of WebAssembly.Module.imports(module)) {
+        imports[descriptor.module] = {}
+        imports[descriptor.module][descriptor.name] = new Function("x", "y", "z", jscode);
+        instance = new WebAssembly.Instance(module, imports);
+        for (let descriptor of WebAssembly.Module.exports(module)) {
+            print(instance.exports[descriptor.name]())
+        }
+    }
+}