Bug 1465695 - Don't release helper thread lock while cancelling off-thread parses r=jandem
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 01 Jun 2018 11:35:57 +0100
changeset 420833 f94a48321c2c15a1b80eb91d3c619924ea3c8faa
parent 420832 f22e28ed197c45e29c5df80e3c91036a976e266d
child 420834 92f6a3f162e735951d9a9762338045586bbb9a54
push id103896
push userjcoppeard@mozilla.com
push dateFri, 01 Jun 2018 10:43:13 +0000
treeherdermozilla-inbound@f94a48321c2c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1465695
milestone62.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 1465695 - Don't release helper thread lock while cancelling off-thread parses r=jandem
js/src/jit-test/tests/parser/bug-1465695.js
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parser/bug-1465695.js
@@ -0,0 +1,4 @@
+if (helperThreadCount() === 0)
+    quit();
+for (let x = 0; x < 99; ++x)
+    evalInWorker("newGlobal().offThreadCompileScript(\"{}\");");
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -638,18 +638,18 @@ js::CancelOffThreadParses(JSRuntime* rt)
     while (true) {
         bool found = false;
         ParseTask* next;
         ParseTask* task = finished.getFirst();
         while (task) {
             next = task->getNext();
             if (task->runtimeMatches(rt)) {
                 found = true;
-                AutoUnlockHelperThreadState unlock(lock);
-                HelperThreadState().cancelParseTask(rt, task->kind, task);
+                task->remove();
+                HelperThreadState().destroyParseTask(rt, task);
             }
             task = next;
         }
         if (!found)
             break;
     }
 
 #ifdef DEBUG
@@ -1637,17 +1637,16 @@ GlobalHelperThreadState::removeFinishedP
         if (t == task) {
             found = true;
             break;
         }
     }
     MOZ_ASSERT(found);
 #endif
 
-
     task->remove();
     return task;
 }
 
 template <typename F, typename>
 bool
 GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind,
                                          JS::OffThreadToken* token, F&& finishCallback)
@@ -1818,18 +1817,25 @@ GlobalHelperThreadState::finishModulePar
 
     return module;
 }
 
 void
 GlobalHelperThreadState::cancelParseTask(JSRuntime* rt, ParseTaskKind kind,
                                          JS::OffThreadToken* token)
 {
-    ScopedJSDeletePtr<ParseTask> parseTask(removeFinishedParseTask(kind, token));
+    destroyParseTask(rt, removeFinishedParseTask(kind, token));
+}
+
+void
+GlobalHelperThreadState::destroyParseTask(JSRuntime* rt, ParseTask* parseTask)
+{
+    MOZ_ASSERT(!parseTask->isInList());
     LeaveParseTaskZone(rt, parseTask);
+    js_delete(parseTask);
 }
 
 void
 GlobalHelperThreadState::mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, Realm* dest)
 {
     // After we call LeaveParseTaskZone() it's not safe to GC until we have
     // finished merging the contents of the parse task's realm into the
     // destination realm.
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -299,16 +299,17 @@ class GlobalHelperThreadState
     >
     bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, F&& finishCallback);
 
     JSScript* finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token);
 
     bool finishParseTask(JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);
 
     void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, JS::OffThreadToken* token);
+    void destroyParseTask(JSRuntime* rt, ParseTask* parseTask);
 
     void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, JS::Realm* dest);
 
     void trace(JSTracer* trc, js::gc::AutoTraceSession& session);
 
     JSScript* finishScriptParseTask(JSContext* cx, JS::OffThreadToken* token);
     JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token);
     bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, MutableHandle<ScriptVector> scripts);