diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
commit | 8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch) | |
tree | 17985605dab9263cc2444bd4d45f189e142cca7c /Source/JavaScriptCore/heap/GCThreadSharedData.cpp | |
parent | b9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff) | |
download | qtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz |
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well
as the previously cherry-picked changes
Diffstat (limited to 'Source/JavaScriptCore/heap/GCThreadSharedData.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/GCThreadSharedData.cpp | 107 |
1 files changed, 76 insertions, 31 deletions
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp index 23a6b97a1..d9946d589 100644 --- a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp @@ -26,45 +26,30 @@ #include "config.h" #include "GCThreadSharedData.h" +#include "CopyVisitor.h" +#include "CopyVisitorInlineMethods.h" +#include "GCThread.h" #include "JSGlobalData.h" #include "MarkStack.h" #include "SlotVisitor.h" #include "SlotVisitorInlineMethods.h" -#include <wtf/MainThread.h> namespace JSC { #if ENABLE(PARALLEL_GC) void GCThreadSharedData::resetChildren() { - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - m_markingThreadsMarkStack[i]->reset(); + for (size_t i = 0; i < m_gcThreads.size(); ++i) + m_gcThreads[i]->slotVisitor()->reset(); } size_t GCThreadSharedData::childVisitCount() { unsigned long result = 0; - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - result += m_markingThreadsMarkStack[i]->visitCount(); + for (unsigned i = 0; i < m_gcThreads.size(); ++i) + result += m_gcThreads[i]->slotVisitor()->visitCount(); return result; } - -void GCThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) -{ - WTF::registerGCThread(); - { - ParallelModeEnabler enabler(*slotVisitor); - slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); - } - delete slotVisitor; -} - -void GCThreadSharedData::markingThreadStartFunc(void* myVisitor) -{ - SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); - - slotVisitor->sharedData().markingThreadMain(slotVisitor); -} #endif GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData) @@ -74,13 +59,21 @@ GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData) , m_sharedMarkStack(m_segmentAllocator) , m_numberOfActiveParallelMarkers(0) , m_parallelMarkersShouldExit(false) + , m_blocksToCopy(globalData->heap.m_blockSnapshot) + , m_copyIndex(0) + , m_currentPhase(NoPhase) { + m_copyLock.Init(); #if ENABLE(PARALLEL_GC) + // Grab the lock so the new GC threads can be properly initialized before they start running. + MutexLocker locker(m_markingLock); for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { SlotVisitor* slotVisitor = new SlotVisitor(*this); - m_markingThreadsMarkStack.append(slotVisitor); - m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); - ASSERT(m_markingThreads.last()); + CopyVisitor* copyVisitor = new CopyVisitor(*this); + GCThread* newThread = new GCThread(*this, slotVisitor, copyVisitor); + ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking"); + newThread->initializeThreadID(threadID); + m_gcThreads.append(newThread); } #endif } @@ -90,19 +83,22 @@ GCThreadSharedData::~GCThreadSharedData() #if ENABLE(PARALLEL_GC) // Destroy our marking threads. { - MutexLocker locker(m_markingLock); + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); m_parallelMarkersShouldExit = true; - m_markingCondition.broadcast(); + m_currentPhase = Exit; + m_phaseCondition.broadcast(); + } + for (unsigned i = 0; i < m_gcThreads.size(); ++i) { + waitForThreadCompletion(m_gcThreads[i]->threadID()); + delete m_gcThreads[i]; } - for (unsigned i = 0; i < m_markingThreads.size(); ++i) - waitForThreadCompletion(m_markingThreads[i]); #endif } void GCThreadSharedData::reset() { - ASSERT(!m_numberOfActiveParallelMarkers); - ASSERT(!m_parallelMarkersShouldExit); ASSERT(m_sharedMarkStack.isEmpty()); #if ENABLE(PARALLEL_GC) @@ -119,4 +115,53 @@ void GCThreadSharedData::reset() } } +void GCThreadSharedData::didStartMarking() +{ + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); + m_currentPhase = Mark; + m_parallelMarkersShouldExit = false; + m_phaseCondition.broadcast(); +} + +void GCThreadSharedData::didFinishMarking() +{ + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == Mark); + m_currentPhase = NoPhase; + m_parallelMarkersShouldExit = true; + m_markingCondition.broadcast(); +} + +void GCThreadSharedData::didStartCopying() +{ + { + SpinLockHolder locker(&m_copyLock); + m_blocksToCopy = m_globalData->heap.m_blockSnapshot; + m_copyIndex = 0; + } + + // We do this here so that we avoid a race condition where the main thread can + // blow through all of the copying work before the GCThreads fully wake up. + // The GCThreads then request a block from the CopiedSpace when the copying phase + // has completed, which isn't allowed. + for (size_t i = 0; i < m_gcThreads.size(); i++) + m_gcThreads[i]->copyVisitor()->startCopying(); + + MutexLocker locker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); + m_currentPhase = Copy; + m_phaseCondition.broadcast(); +} + +void GCThreadSharedData::didFinishCopying() +{ + MutexLocker locker(m_phaseLock); + ASSERT(m_currentPhase == Copy); + m_currentPhase = NoPhase; + m_phaseCondition.broadcast(); +} + } // namespace JSC |