Bug 1347644 - Fix possible deadlock with PromiseHelperTasks (r=lth)
authorLuke Wagner <luke@mozilla.com>
Fri, 06 Oct 2017 10:41:22 -0500
changeset 676131 6c386d38608af90a93907b01eb6b0082e67463b0
parent 676130 f61947de473fa09f3a8aba90ee6eab92d5f0ad80
child 676132 fd99f3454c510f766a19f7c6ea86f6278227b5a0
push id83398
push userbmo:rail@mozilla.com
push dateFri, 06 Oct 2017 17:12:44 +0000
reviewerslth
bugs1347644
milestone58.0a1
Bug 1347644 - Fix possible deadlock with PromiseHelperTasks (r=lth) MozReview-Commit-ID: 2aR2V1Dt4Bl
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -1173,16 +1173,24 @@ GlobalHelperThreadState::maxWasmCompilat
 
 size_t
 GlobalHelperThreadState::maxWasmTier2GeneratorThreads() const
 {
     return MaxTier2GeneratorTasks;
 }
 
 size_t
+GlobalHelperThreadState::maxPromiseHelperThreads() const
+{
+    if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_WASM))
+        return 1;
+    return cpuCount;
+}
+
+size_t
 GlobalHelperThreadState::maxParseThreads() const
 {
     if (IsHelperThreadSimulatingOOM(js::THREAD_TYPE_PARSE))
         return 1;
 
     // Don't allow simultaneous off thread parses, to reduce contention on the
     // atoms table. Note that wasm compilation depends on this to avoid
     // stalling the helper thread, as off thread parse tasks can trigger and
@@ -1263,17 +1271,21 @@ GlobalHelperThreadState::canStartWasmTie
     return !wasmTier2GeneratorWorklist(lock).empty() &&
            checkTaskThreadLimit<wasm::Tier2GeneratorTask*>(maxWasmTier2GeneratorThreads(),
                                                            /*isMaster=*/true);
 }
 
 bool
 GlobalHelperThreadState::canStartPromiseHelperTask(const AutoLockHelperThreadState& lock)
 {
-    return !promiseHelperTasks(lock).empty();
+    // PromiseHelperTasks can be wasm compilation tasks that in turn block on
+    // wasm compilation so set isMaster = true.
+    return !promiseHelperTasks(lock).empty() &&
+           checkTaskThreadLimit<PromiseHelperTask*>(maxPromiseHelperThreads(),
+                                                    /*isMaster=*/true);
 }
 
 static bool
 IonBuilderHasHigherPriority(jit::IonBuilder* first, jit::IonBuilder* second)
 {
     // Return true if priority(first) > priority(second).
     //
     // This method can return whatever it wants, though it really ought to be a
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -141,16 +141,17 @@ class GlobalHelperThreadState
     GCParallelTaskVector gcParallelWorklist_;
 
     ParseTask* removeFinishedParseTask(ParseTaskKind kind, void* token);
 
   public:
     size_t maxIonCompilationThreads() const;
     size_t maxWasmCompilationThreads() const;
     size_t maxWasmTier2GeneratorThreads() const;
+    size_t maxPromiseHelperThreads() const;
     size_t maxParseThreads() const;
     size_t maxCompressionThreads() const;
     size_t maxGCHelperThreads() const;
     size_t maxGCParallelThreads() const;
 
     GlobalHelperThreadState();
 
     bool ensureInitialized();