Bug 1062629 - Off-thread compartment debug mode should match main thread compartment debug mode. (r=jimb)
authorShu-yu Guo <shu@rfrn.org>
Thu, 13 Nov 2014 14:39:40 -0800
changeset 215676 bb2f13ba7b1cceeb491e876773196c0aad71ef95
parent 215675 b160657339f8e05bca3649d31d52481a25de188c
child 215677 1176cc3c3b3476a04b8b9a7f1629c9d8edd4b779
push id27823
push usercbook@mozilla.com
push dateFri, 14 Nov 2014 11:59:57 +0000
treeherdermozilla-central@bbb68df450c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1062629
milestone36.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 1062629 - Off-thread compartment debug mode should match main thread compartment debug mode. (r=jimb)
js/src/jit-test/tests/debug/onNewScript-off-main-thread-01.js
js/src/jit-test/tests/debug/onNewScript-off-main-thread-02.js
js/src/jit-test/tests/debug/onNewScript-off-main-thread.js
js/src/jscompartment.cpp
js/src/jsgc.cpp
js/src/vm/HelperThreads.cpp
rename from js/src/jit-test/tests/debug/onNewScript-off-main-thread.js
rename to js/src/jit-test/tests/debug/onNewScript-off-main-thread-01.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/onNewScript-off-main-thread-02.js
@@ -0,0 +1,13 @@
+if (helperThreadCount() === 0)
+  quit(0);
+
+var global = newGlobal();
+var dbg = new Debugger(global);
+
+dbg.onNewScript = function (s) {
+  if (s.url === "<string>")
+    assertEq(s.getChildScripts().length, 1);
+};
+
+global.eval('offThreadCompileScript("function inner() { \\\"use asm\\\"; function xxx() {} return xxx; }");');
+global.eval('runOffThreadScript();');
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -558,17 +558,22 @@ JSCompartment::sweepSavedStacks()
 {
     savedStacks_.sweep(runtimeFromAnyThread());
 }
 
 void
 JSCompartment::sweepGlobalObject(FreeOp *fop)
 {
     if (global_.unbarrieredGet() && IsObjectAboutToBeFinalizedFromAnyThread(global_.unsafeGet())) {
-        if (isDebuggee())
+        // For main thread compartments, the invariant is that debug mode
+        // implies having at least one Debugger still attached. However, for
+        // off-thread compartments, which are used in off-thread parsing, they
+        // may be isDebuggee() without there being any Debuggers to prohibit
+        // asm.js.
+        if (isDebuggee() && !global_->compartment()->options().invisibleToDebugger())
             Debugger::detachAllDebuggersFromGlobal(fop, global_);
         global_.set(nullptr);
     }
 }
 
 void
 JSCompartment::sweepSelfHostingScriptSource()
 {
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -6430,16 +6430,17 @@ gc::MergeCompartments(JSCompartment *sou
     JSRuntime *rt = source->runtimeFromMainThread();
 
     AutoPrepareForTracing prepare(rt, SkipAtoms);
 
     // Cleanup tables and other state in the source compartment that will be
     // meaningless after merging into the target compartment.
 
     source->clearTables();
+    source->unsetIsDebuggee();
 
     // Fixup compartment pointers in source to refer to target, and make sure
     // type information generations are in sync.
 
     for (ZoneCellIter iter(source->zone(), FINALIZE_SCRIPT); !iter.done(); iter.next()) {
         JSScript *script = iter.get<JSScript>();
         MOZ_ASSERT(script->compartment() == source);
         script->compartment_ = target;
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -360,16 +360,22 @@ js::StartOffThreadParseScript(JSContext 
 
     if (OffThreadParsingMustWaitForGC(cx->runtime())) {
         AutoLockHelperThreadState lock;
         if (!HelperThreadState().parseWaitingOnGC().append(task.get()))
             return false;
     } else {
         task->activate(cx->runtime());
 
+        if (cx->compartment()->isDebuggee()) {
+            task->cx->compartment()->setIsDebuggee();
+            if (cx->compartment()->debugObservesAllExecution())
+                task->cx->compartment()->setDebugObservesAllExecution();
+        }
+
         AutoLockHelperThreadState lock;
 
         if (!HelperThreadState().parseWorklist().append(task.get()))
             return false;
 
         HelperThreadState().notifyOne(GlobalHelperThreadState::PRODUCER);
     }