WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
it begins
blah.patch (text/plain), 25.84 KB, created by
Filip Pizlo
on 2015-09-22 15:23:05 PDT
(
hide
)
Description:
it begins
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2015-09-22 15:23:05 PDT
Size:
25.84 KB
patch
obsolete
>Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 190131) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -1657,8 +1657,6 @@ > BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; }; > C20328201981979D0088B499 /* CustomGlobalObjectClassTest.c in Sources */ = {isa = PBXBuildFile; fileRef = C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */; }; > C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; }; >- C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; > C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > C2181FC218A948FB0025A235 /* JSExportTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2181FC118A948FB0025A235 /* JSExportTests.mm */; }; > C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */ = {isa = PBXBuildFile; fileRef = C218D13F1655CFD50062BB81 /* CopyWorkList.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -3529,8 +3527,6 @@ > C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CustomGlobalObjectClassTest.c; path = API/tests/CustomGlobalObjectClassTest.c; sourceTree = "<group>"; }; > C203281F1981979D0088B499 /* CustomGlobalObjectClassTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomGlobalObjectClassTest.h; path = API/tests/CustomGlobalObjectClassTest.h; sourceTree = "<group>"; }; > C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.h; sourceTree = "<group>"; }; >- C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; }; >- C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; }; > C211B574176A224D000E2A23 /* APICallbackFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APICallbackFunction.h; sourceTree = "<group>"; }; > C2181FC018A948FB0025A235 /* JSExportTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSExportTests.h; path = API/tests/JSExportTests.h; sourceTree = "<group>"; }; > C2181FC118A948FB0025A235 /* JSExportTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = JSExportTests.mm; path = API/tests/JSExportTests.mm; sourceTree = "<group>"; }; >@@ -4255,8 +4251,6 @@ > 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */, > C2239D1516262BDD005AC5FD /* GCThread.cpp */, > C2239D1616262BDD005AC5FD /* GCThread.h */, >- C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */, >- C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */, > 142E312B134FF0A600AFADB5 /* Handle.h */, > C28318FF16FE4B7D00157BFD /* HandleBlock.h */, > C283190116FE533E00157BFD /* HandleBlockInlines.h */, >@@ -6401,7 +6395,6 @@ > 0F2B66AE17B6B54500A7AE3F /* GCIncomingRefCountedSet.h in Headers */, > 0F2B66AF17B6B54500A7AE3F /* GCIncomingRefCountedSetInlines.h in Headers */, > C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */, >- C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, > 0F2B66E017B6B5AB00A7AE3F /* GenericTypedArrayView.h in Headers */, > 0F1FE51C1922A3BC006987C5 /* AbortReason.h in Headers */, > 0F2B66E117B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h in Headers */, >@@ -7723,7 +7716,6 @@ > 0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */, > 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */, > C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */, >- C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */, > 0F93329F14CA7DCA0085F3C6 /* GetByIdStatus.cpp in Sources */, > 0F0332C318B01763005F979A /* GetByIdVariant.cpp in Sources */, > 14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */, >Index: Source/JavaScriptCore/heap/GCThreadSharedData.cpp >=================================================================== >--- Source/JavaScriptCore/heap/GCThreadSharedData.cpp (revision 190131) >+++ Source/JavaScriptCore/heap/GCThreadSharedData.cpp (working copy) >@@ -1,199 +0,0 @@ >-/* >- * Copyright (C) 2009, 2011, 2015 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "GCThreadSharedData.h" >- >-#include "CopyVisitor.h" >-#include "CopyVisitorInlines.h" >-#include "GCThread.h" >-#include "MarkStack.h" >-#include "JSCInlines.h" >-#include "SlotVisitor.h" >-#include "SlotVisitorInlines.h" >-#include "VM.h" >- >-namespace JSC { >- >-void GCThreadSharedData::resetChildren() >-{ >- 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_gcThreads.size(); ++i) >- result += m_gcThreads[i]->slotVisitor()->visitCount(); >- return result; >-} >- >-size_t GCThreadSharedData::childBytesVisited() >-{ >- size_t result = 0; >- for (unsigned i = 0; i < m_gcThreads.size(); ++i) >- result += m_gcThreads[i]->slotVisitor()->bytesVisited(); >- return result; >-} >- >-size_t GCThreadSharedData::childBytesCopied() >-{ >- size_t result = 0; >- for (unsigned i = 0; i < m_gcThreads.size(); ++i) >- result += m_gcThreads[i]->slotVisitor()->bytesCopied(); >- return result; >-} >- >-GCThreadSharedData::GCThreadSharedData(VM* vm) >- : m_vm(vm) >- , m_copiedSpace(&vm->heap.m_storageSpace) >- , m_shouldHashCons(false) >- , m_sharedMarkStack() >- , m_numberOfActiveParallelMarkers(0) >- , m_parallelMarkersShouldExit(false) >- , m_copyIndex(0) >- , m_numberOfActiveGCThreads(0) >- , m_gcThreadsShouldWait(false) >- , m_currentPhase(NoPhase) >-{ >- // Grab the lock so the new GC threads can be properly initialized before they start running. >- std::unique_lock<Lock> lock(m_phaseMutex); >- for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { >- m_numberOfActiveGCThreads++; >- GCThread* newThread = new GCThread(*this, std::make_unique<SlotVisitor>(*this), std::make_unique<CopyVisitor>(*this)); >- ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking"); >- newThread->initializeThreadID(threadID); >- m_gcThreads.append(newThread); >- } >- >- // Wait for all the GCThreads to get to the right place. >- m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; }); >-} >- >-GCThreadSharedData::~GCThreadSharedData() >-{ >- // Destroy our marking threads. >- { >- std::lock_guard<Lock> markingLock(m_markingMutex); >- std::lock_guard<Lock> phaseLock(m_phaseMutex); >- ASSERT(m_currentPhase == NoPhase); >- m_parallelMarkersShouldExit = true; >- m_gcThreadsShouldWait = false; >- m_currentPhase = Exit; >- m_phaseConditionVariable.notifyAll(); >- } >- for (unsigned i = 0; i < m_gcThreads.size(); ++i) { >- waitForThreadCompletion(m_gcThreads[i]->threadID()); >- delete m_gcThreads[i]; >- } >-} >- >-void GCThreadSharedData::reset() >-{ >- ASSERT(m_sharedMarkStack.isEmpty()); >- >- m_weakReferenceHarvesters.removeAll(); >- >- if (m_shouldHashCons) { >- m_vm->resetNewStringsSinceLastHashCons(); >- m_shouldHashCons = false; >- } >-} >- >-void GCThreadSharedData::startNextPhase(GCPhase phase) >-{ >- std::lock_guard<Lock> lock(m_phaseMutex); >- ASSERT(!m_gcThreadsShouldWait); >- ASSERT(m_currentPhase == NoPhase); >- m_gcThreadsShouldWait = true; >- m_currentPhase = phase; >- m_phaseConditionVariable.notifyAll(); >-} >- >-void GCThreadSharedData::endCurrentPhase() >-{ >- ASSERT(m_gcThreadsShouldWait); >- std::unique_lock<Lock> lock(m_phaseMutex); >- m_currentPhase = NoPhase; >- m_gcThreadsShouldWait = false; >- m_phaseConditionVariable.notifyAll(); >- m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; }); >-} >- >-void GCThreadSharedData::didStartMarking() >-{ >- if (m_vm->heap.operationInProgress() == FullCollection) >- m_opaqueRoots.clear(); >- std::lock_guard<Lock> lock(m_markingMutex); >- m_parallelMarkersShouldExit = false; >- startNextPhase(Mark); >-} >- >-void GCThreadSharedData::didFinishMarking() >-{ >- { >- std::lock_guard<Lock> lock(m_markingMutex); >- m_parallelMarkersShouldExit = true; >- m_markingConditionVariable.notifyAll(); >- } >- >- ASSERT(m_currentPhase == Mark); >- endCurrentPhase(); >-} >- >-void GCThreadSharedData::didStartCopying() >-{ >- { >- LockHolder locker(&m_copyLock); >- if (m_vm->heap.operationInProgress() == EdenCollection) { >- // Reset the vector to be empty, but don't throw away the backing store. >- m_blocksToCopy.shrink(0); >- for (CopiedBlock* block = m_copiedSpace->m_newGen.fromSpace->head(); block; block = block->next()) >- m_blocksToCopy.append(block); >- } else { >- ASSERT(m_vm->heap.operationInProgress() == FullCollection); >- WTF::copyToVector(m_copiedSpace->m_blockSet, m_blocksToCopy); >- } >- 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(); >- >- startNextPhase(Copy); >-} >- >-void GCThreadSharedData::didFinishCopying() >-{ >- ASSERT(m_currentPhase == Copy); >- endCurrentPhase(); >-} >- >-} // namespace JSC >Index: Source/JavaScriptCore/heap/GCThreadSharedData.h >=================================================================== >--- Source/JavaScriptCore/heap/GCThreadSharedData.h (revision 190131) >+++ Source/JavaScriptCore/heap/GCThreadSharedData.h (working copy) >@@ -1,125 +0,0 @@ >-/* >- * Copyright (C) 2009, 2011, 2015 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#ifndef GCThreadSharedData_h >-#define GCThreadSharedData_h >- >-#include "ListableHandler.h" >-#include "MarkStack.h" >-#include "MarkedBlock.h" >-#include "UnconditionalFinalizer.h" >-#include "WeakReferenceHarvester.h" >-#include <condition_variable> >-#include <wtf/Condition.h> >-#include <wtf/HashSet.h> >-#include <wtf/Lock.h> >-#include <wtf/Vector.h> >- >-namespace JSC { >- >-class CopiedBlock; >-class CopiedSpace; >-class CopyVisitor; >-class GCThread; >-class VM; >- >-enum GCPhase { >- NoPhase, >- Mark, >- Copy, >- Exit >-}; >- >-class GCThreadSharedData { >- WTF_MAKE_FAST_ALLOCATED; >-public: >- GCThreadSharedData(VM*); >- ~GCThreadSharedData(); >- >- void reset(); >- >- void didStartMarking(); >- void didFinishMarking(); >- void didStartCopying(); >- void didFinishCopying(); >- >- void resetChildren(); >- size_t childVisitCount(); >- size_t childBytesVisited(); >- size_t childBytesCopied(); >- size_t childDupStrings(); >- >-private: >- friend class GCThread; >- friend class SlotVisitor; >- friend class CopyVisitor; >- >- void getNextBlocksToCopy(size_t&, size_t&); >- void startNextPhase(GCPhase); >- void endCurrentPhase(); >- >- VM* m_vm; >- CopiedSpace* m_copiedSpace; >- >- bool m_shouldHashCons; >- >- Vector<GCThread*> m_gcThreads; >- >- Lock m_markingMutex; >- Condition m_markingConditionVariable; >- MarkStackArray m_sharedMarkStack; >- unsigned m_numberOfActiveParallelMarkers; >- bool m_parallelMarkersShouldExit; >- >- Lock m_opaqueRootsMutex; >- HashSet<void*> m_opaqueRoots; >- >- Lock m_copyLock; >- Vector<CopiedBlock*> m_blocksToCopy; >- size_t m_copyIndex; >- static const size_t s_blockFragmentLength = 32; >- >- Lock m_phaseMutex; >- Condition m_phaseConditionVariable; >- Condition m_activityConditionVariable; >- unsigned m_numberOfActiveGCThreads; >- bool m_gcThreadsShouldWait; >- GCPhase m_currentPhase; >- >- ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; >- ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; >-}; >- >-inline void GCThreadSharedData::getNextBlocksToCopy(size_t& start, size_t& end) >-{ >- LockHolder locker(&m_copyLock); >- start = m_copyIndex; >- end = std::min(m_blocksToCopy.size(), m_copyIndex + s_blockFragmentLength); >- m_copyIndex = end; >-} >- >-} // namespace JSC >- >-#endif >Index: Source/JavaScriptCore/heap/Heap.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Heap.cpp (revision 190131) >+++ Source/JavaScriptCore/heap/Heap.cpp (working copy) >@@ -335,7 +335,6 @@ Heap::Heap(VM* vm, HeapType heapType) > , m_extraMemorySize(0) > , m_deprecatedExtraMemorySize(0) > , m_machineThreads(this) >- , m_sharedData(vm) > , m_slotVisitor(m_sharedData) > , m_copyVisitor(m_sharedData) > , m_handleSet(vm) >@@ -358,6 +357,21 @@ Heap::Heap(VM* vm, HeapType heapType) > , m_delayedReleaseRecursionCount(0) > #endif > { >+ { >+ // Grab the lock so the new GC threads can be properly initialized before they start running. >+ std::unique_lock<Lock> lock(m_phaseMutex); >+ for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { >+ m_numberOfActiveGCThreads++; >+ GCThread* newThread = new GCThread(*this, std::make_unique<SlotVisitor>(*this), std::make_unique<CopyVisitor>(*this)); >+ ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking"); >+ newThread->initializeThreadID(threadID); >+ m_gcThreads.append(newThread); >+ } >+ >+ // Wait for all the GCThreads to get to the right place. >+ m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; }); >+ } >+ > m_storageSpace.init(); > if (Options::verifyHeap()) > m_verifier = std::make_unique<HeapVerifier>(this, Options::numberOfGCCyclesToRecordForVerification()); >@@ -367,6 +381,21 @@ Heap::~Heap() > { > for (WeakBlock* block : m_logicallyEmptyWeakBlocks) > WeakBlock::destroy(block); >+ >+ // Destroy our marking threads. >+ { >+ std::lock_guard<Lock> markingLock(m_markingMutex); >+ std::lock_guard<Lock> phaseLock(m_phaseMutex); >+ ASSERT(m_currentPhase == NoPhase); >+ m_parallelMarkersShouldExit = true; >+ m_gcThreadsShouldWait = false; >+ m_currentPhase = Exit; >+ m_phaseConditionVariable.notifyAll(); >+ } >+ for (unsigned i = 0; i < m_gcThreads.size(); ++i) { >+ waitForThreadCompletion(m_gcThreads[i]->threadID()); >+ delete m_gcThreads[i]; >+ } > } > > bool Heap::isPagedOut(double deadline) >@@ -539,7 +568,13 @@ void Heap::markRoots(double gcStartTime, > > clearLivenessData(); > >- m_sharedData.didStartMarking(); >+ if (m_operationInProgress == FullCollection) >+ m_opaqueRoots.clear(); >+ { >+ std::lock_guard<Lock> lock(m_markingMutex); >+ m_parallelMarkersShouldExit = false; >+ startNextPhase(Mark); >+ } > m_slotVisitor.didStartMarking(); > HeapRootVisitor heapRootVisitor(m_slotVisitor); > >@@ -563,7 +598,13 @@ void Heap::markRoots(double gcStartTime, > visitWeakHandles(heapRootVisitor); > > clearRememberedSet(rememberedSet); >- m_sharedData.didFinishMarking(); >+ { >+ std::lock_guard<Lock> lock(m_markingMutex); >+ m_parallelMarkersShouldExit = true; >+ m_markingConditionVariable.notifyAll(); >+ } >+ ASSERT(m_currentPhase == Mark); >+ endCurrentPhase(); > updateObjectCounts(gcStartTime); > resetVisitors(); > } >@@ -579,14 +620,37 @@ void Heap::copyBackingStores() > } > > if (m_storageSpace.shouldDoCopyPhase()) { >- m_sharedData.didStartCopying(); >+ { >+ LockHolder locker(m_copyLock); >+ if (m_operationInProgress == EdenCollection) { >+ // Reset the vector to be empty, but don't throw away the backing store. >+ m_blocksToCopy.shrink(0); >+ for (CopiedBlock* block = m_storageSpace->m_newGen.fromSpace->head(); block; block = block->next()) >+ m_blocksToCopy.append(block); >+ } else { >+ ASSERT(m_operationInProgress == FullCollection); >+ WTF::copyToVector(m_storageSpace->m_blockSet, m_blocksToCopy); >+ } >+ 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(); >+ >+ startNextPhase(Copy); >+ > m_copyVisitor.startCopying(); > m_copyVisitor.copyFromShared(); > m_copyVisitor.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(); >+ ASSERT(m_currentPhase == Copy); >+ endCurrentPhase(); > } else > m_storageSpace.doneCopying(); > } >@@ -813,8 +877,16 @@ void Heap::updateObjectCounts(double gcS > void Heap::resetVisitors() > { > m_slotVisitor.reset(); >- m_sharedData.resetChildren(); >- m_sharedData.reset(); >+ >+ for (GCThread* thread : m_gcThreads) >+ thread->slotVisitor()->reset(); >+ >+ ASSERT(m_sharedMarkStack.isEmpty()); >+ m_weakReferenceHarvesters.removeAll(); >+ if (m_shouldHashCons) { >+ m_vm->resetNewStringsSinceLastHashCons(); >+ m_shouldHashCons = false; >+ } > } > > size_t Heap::objectCount() >@@ -1465,4 +1537,48 @@ bool Heap::sweepNextLogicallyEmptyWeakBl > return true; > } > >+size_t Heap::threadVisitCount() >+{ >+ unsigned long result = 0; >+ for (unsigned i = 0; i < m_gcThreads.size(); ++i) >+ result += m_gcThreads[i]->slotVisitor()->visitCount(); >+ return result; >+} >+ >+size_t Heap::threadBytesVisited() >+{ >+ size_t result = 0; >+ for (unsigned i = 0; i < m_gcThreads.size(); ++i) >+ result += m_gcThreads[i]->slotVisitor()->bytesVisited(); >+ return result; >+} >+ >+size_t Heap::threadBytesCopied() >+{ >+ size_t result = 0; >+ for (unsigned i = 0; i < m_gcThreads.size(); ++i) >+ result += m_gcThreads[i]->slotVisitor()->bytesCopied(); >+ return result; >+} >+ >+void Heap::startNextPhase(GCPhase phase) >+{ >+ std::lock_guard<Lock> lock(m_phaseMutex); >+ ASSERT(!m_gcThreadsShouldWait); >+ ASSERT(m_currentPhase == NoPhase); >+ m_gcThreadsShouldWait = true; >+ m_currentPhase = phase; >+ m_phaseConditionVariable.notifyAll(); >+} >+ >+void Heap::endCurrentPhase() >+{ >+ ASSERT(m_gcThreadsShouldWait); >+ std::unique_lock<Lock> lock(m_phaseMutex); >+ m_currentPhase = NoPhase; >+ m_gcThreadsShouldWait = false; >+ m_phaseConditionVariable.notifyAll(); >+ m_activityConditionVariable.wait(lock, [this] { return !m_numberOfActiveGCThreads; }); >+} >+ > } // namespace JSC >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 190131) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -26,7 +26,6 @@ > #include "CodeBlockSet.h" > #include "CopyVisitor.h" > #include "GCIncomingRefCountedSet.h" >-#include "GCThreadSharedData.h" > #include "HandleSet.h" > #include "HandleStack.h" > #include "HeapOperation.h" >@@ -80,12 +79,18 @@ typedef HashCountedSet<const char*> Type > > enum HeapType { SmallHeap, LargeHeap }; > >+enum GCPhase { >+ NoPhase, >+ Mark, >+ Copy, >+ Exit >+}; >+ > class Heap { > WTF_MAKE_NONCOPYABLE(Heap); > public: > friend class JIT; > friend class DFG::SpeculativeJIT; >- friend class GCThreadSharedData; > static Heap* heap(const JSValue); // 0 for immediate values > static Heap* heap(const JSCell*); > >@@ -243,6 +248,7 @@ private: > friend class DeferGCForAWhile; > friend class GCAwareJITStubRoutine; > friend class GCLogging; >+ friend class GCThread; > friend class HandleSet; > friend class HeapVerifier; > friend class JITStubRoutine; >@@ -339,6 +345,15 @@ private: > void decrementDeferralDepth(); > void decrementDeferralDepthAndGCIfNeeded(); > >+ size_t threadVisitCount(); >+ size_t threadBytesVisited(); >+ size_t threadBytesCopied(); >+ size_t threadDupStrings(); >+ >+ void getNextBlocksToCopy(size_t&, size_t&); >+ void startNextPhase(GCPhase); >+ void endCurrentPhase(); >+ > const HeapType m_heapType; > const size_t m_ramSize; > const size_t m_minBytesPerCycle; >@@ -371,7 +386,6 @@ private: > > MachineThreads m_machineThreads; > >- GCThreadSharedData m_sharedData; > SlotVisitor m_slotVisitor; > CopyVisitor m_copyVisitor; > >@@ -409,6 +423,34 @@ private: > #endif > > HashMap<void*, std::function<void()>> m_weakGCMaps; >+ >+ bool m_shouldHashCons { false }; >+ >+ Vector<GCThread*> m_gcThreads; >+ >+ Lock m_markingMutex; >+ Condition m_markingConditionVariable; >+ MarkStackArray m_sharedMarkStack; >+ unsigned m_numberOfActiveParallelMarkers { 0 }; >+ bool m_parallelMarkersShouldExit { false }; >+ >+ Lock m_opaqueRootsMutex; >+ HashSet<void*> m_opaqueRoots; >+ >+ Lock m_copyLock; >+ Vector<CopiedBlock*> m_blocksToCopy; >+ size_t m_copyIndex { 0 }; >+ static const size_t s_blockFragmentLength = 32; >+ >+ Lock m_phaseMutex; >+ Condition m_phaseConditionVariable; >+ Condition m_activityConditionVariable; >+ unsigned m_numberOfActiveGCThreads { 0 }; >+ bool m_gcThreadsShouldWait { false }; >+ GCPhase m_currentPhase { NoPhase }; >+ >+ ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; >+ ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; > }; > > } // namespace JSC >Index: Source/JavaScriptCore/heap/HeapInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/HeapInlines.h (revision 190131) >+++ Source/JavaScriptCore/heap/HeapInlines.h (working copy) >@@ -326,6 +326,14 @@ inline void Heap::unregisterWeakGCMap(vo > m_weakGCMaps.remove(weakGCMap); > } > >+inline void Heap::getNextBlocksToCopy(size_t& start, size_t& end) >+{ >+ LockHolder locker(m_copyLock); >+ start = m_copyIndex; >+ end = std::min(m_blocksToCopy.size(), m_copyIndex + s_blockFragmentLength); >+ m_copyIndex = end; >+} >+ > } // namespace JSC > > #endif // HeapInlines_h
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 149435
:
261769
|
261775
|
261781