Bug 1486556 - Avoid unlocking the helper thread state lock after looking for tasks to perform, r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 31 Aug 2018 05:21:44 -1000
changeset 434424 dcecbdfea1143b1ff7e2fdd8466fbc7c5ec393e2
parent 434421 354e37362d068f8f120d759c6ed61507f46c2918
child 434425 641bced4e9865e99488f5f222ae774d4e69db4ce
push id34557
push userdluca@mozilla.com
push dateSun, 02 Sep 2018 21:34:34 +0000
treeherdermozilla-central@634b562ae2c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1486556
milestone63.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 1486556 - Avoid unlocking the helper thread state lock after looking for tasks to perform, r=jandem.
js/src/vm/HelperThreads.cpp
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -2418,38 +2418,42 @@ HelperThread::threadLoop()
             oomUnsafe.crash("HelperThread cx.init()");
     }
     cx.setHelperThread(this);
     JS_SetNativeStackQuota(&cx, HELPER_STACK_QUOTA);
 
     while (!terminate) {
         MOZ_ASSERT(idle());
 
+        if (mozilla::recordreplay::IsRecordingOrReplaying()) {
+            // Unlock the helper thread state lock before potentially
+            // blocking while the main thread waits for all threads to
+            // become idle. Otherwise we would need to see if we need to
+            // block at every point where a helper thread acquires the
+            // helper thread state lock.
+            {
+                AutoUnlockHelperThreadState unlock(lock);
+                mozilla::recordreplay::MaybeWaitForCheckpointSave();
+            }
+            // Now that we are holding the helper thread state lock again,
+            // notify the record/replay system that we might block soon.
+            // The helper thread state lock may not be released until the
+            // block occurs.
+            mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll);
+        }
+
         // The selectors may depend on the HelperThreadState not changing
         // between task selection and task execution, in particular, on new
         // tasks not being added (because of the lifo structure of the work
         // lists). Unlocking the HelperThreadState between task selection and
         // execution is not well-defined.
 
         const TaskSpec* task = findHighestPriorityTask(lock);
         if (!task) {
             AUTO_PROFILER_LABEL("HelperThread::threadLoop::wait", IDLE);
-            if (mozilla::recordreplay::IsRecordingOrReplaying()) {
-                // Unlock the helper thread state lock before potentially
-                // blocking while the main thread waits for all threads to
-                // become idle. Otherwise we would need to see if we need to
-                // block at every point where a helper thread acquires the
-                // helper thread state lock.
-                {
-                    AutoUnlockHelperThreadState unlock(lock);
-                    mozilla::recordreplay::MaybeWaitForCheckpointSave();
-                }
-                mozilla::recordreplay::NotifyUnrecordedWait(WakeupAll);
-            }
-
             HelperThreadState().wait(lock, GlobalHelperThreadState::PRODUCER);
             continue;
         }
 
         js::oom::SetThreadType(task->type);
         (this->*(task->handleWorkload))(lock);
         js::oom::SetThreadType(js::THREAD_TYPE_NONE);
     }