Race condition during CopyingPhase can lead to deadlock
https://bugs.webkit.org/show_bug.cgi?id=99226
Reviewed by Filip Pizlo.
The main thread calls startCopying() for each of the GCThreads at the beginning of the copy phase.
It then proceeds to start copying. If copying completes before one of the GCThreads wakes up, the
main thread will set m_currentPhase back to NoPhase, the GCThread will wake up, see that there's
nothing to do, and then it will go back to sleep without ever calling CopyVisitor::doneCopying()
to return its borrowed block to the CopiedSpace. CopiedSpace::doneCopying() will then sleep forever
waiting on the block.
The fix for this is to make sure we call CopiedSpace::doneCopying() on the main thread before we
call GCThreadSharedData::didFinishCopying(), which sets the m_currentPhase flag to NoPhase. This
way we will wait until all threads have woken up and given back their borrowed blocks before
clearing the flag.
* heap/Heap.cpp:
(JSC::Heap::copyBackingStores):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@131244 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 83a8d56..772d851 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -616,9 +616,12 @@
visitor.startCopying();
visitor.copyFromShared();
visitor.doneCopying();
+ // We need to wait for everybody to finish and return their CopiedBlocks
+ // before signaling that the phase is complete.
+ m_storageSpace.doneCopying();
m_sharedData.didFinishCopying();
- }
- m_storageSpace.doneCopying();
+ } else
+ m_storageSpace.doneCopying();
}
size_t Heap::objectCount()