Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (164861 => 164862)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2014-02-28 16:35:27 UTC (rev 164861)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2014-02-28 16:56:17 UTC (rev 164862)
@@ -369,13 +369,6 @@
}
}
-void Heap::markProtectedObjects(HeapRootVisitor& heapRootVisitor)
-{
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- heapRootVisitor.visit(&it->key);
-}
-
void Heap::pushTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempVector)
{
m_tempSortingVectors.append(tempVector);
@@ -387,22 +380,6 @@
m_tempSortingVectors.removeLast();
}
-void Heap::markTempSortVectors(HeapRootVisitor& heapRootVisitor)
-{
- typedef Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>* > VectorOfValueStringVectors;
-
- VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
- for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
- Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempSortingVector = *it;
-
- Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
- for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
- if (vectorIt->first)
- heapRootVisitor.visit(&vectorIt->first);
- }
- }
-}
-
void Heap::harvestWeakReferences()
{
m_slotVisitor.harvestWeakReferences();
@@ -410,6 +387,7 @@
void Heap::finalizeUnconditionalFinalizers()
{
+ GCPHASE(FinalizeUnconditionalFinalizers);
m_slotVisitor.finalizeUnconditionalFinalizers();
}
@@ -444,7 +422,7 @@
void Heap::markRoots()
{
- SamplingRegion samplingRegion("Garbage Collection: Tracing");
+ SamplingRegion samplingRegion("Garbage Collection: Marking");
GCPHASE(MarkRoots);
ASSERT(isValidThreadState(m_vm));
@@ -454,45 +432,22 @@
#endif
m_codeBlocks.clearMarks();
- void* dummy;
// We gather conservative roots before clearing mark bits because conservative
// gathering uses the mark bits to determine whether a reference is valid.
- ConservativeRoots machineThreadRoots(&m_objectSpace.blocks(), &m_storageSpace);
- m_jitStubRoutines.clearMarks();
- {
- GCPHASE(GatherConservativeRoots);
- m_machineThreads.gatherConservativeRoots(machineThreadRoots, m_jitStubRoutines, m_codeBlocks, &dummy);
- }
+ void* dummy;
+ ConservativeRoots conservativeRoots(&m_objectSpace.blocks(), &m_storageSpace);
+ gatherStackRoots(conservativeRoots, &dummy);
+ gatherJSStackRoots(conservativeRoots);
+ gatherScratchBufferRoots(conservativeRoots);
-#if ENABLE(LLINT_C_LOOP)
- ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace);
- {
- GCPHASE(GatherStackRoots);
- stack().gatherConservativeRoots(stackRoots, m_jitStubRoutines, m_codeBlocks);
- }
-#endif
-
sanitizeStackForVM(m_vm);
-#if ENABLE(DFG_JIT)
- ConservativeRoots scratchBufferRoots(&m_objectSpace.blocks(), &m_storageSpace);
- {
- GCPHASE(GatherScratchBufferRoots);
- m_vm->gatherConservativeRoots(scratchBufferRoots);
- }
-#endif
+ clearLivenessData();
- {
- GCPHASE(ClearLivenessData);
- m_objectSpace.clearNewlyAllocated();
- m_objectSpace.clearMarks();
- }
-
m_sharedData.didStartMarking();
- SlotVisitor& visitor = m_slotVisitor;
- visitor.didStartMarking();
- HeapRootVisitor heapRootVisitor(visitor);
+ m_slotVisitor.didStartMarking();
+ HeapRootVisitor heapRootVisitor(m_slotVisitor);
#if ENABLE(GGC)
Vector<const JSCell*> rememberedSet(m_slotVisitor.markStack().size());
@@ -500,133 +455,236 @@
#endif
{
- ParallelModeEnabler enabler(visitor);
+ ParallelModeEnabler enabler(m_slotVisitor);
- m_vm->smallStrings.visitStrongReferences(visitor);
+ visitSmallStrings();
+ visitConservativeRoots(conservativeRoots);
+ visitCompilerWorklists();
+ visitProtectedObjects(heapRootVisitor);
+ visitTempSortVectors(heapRootVisitor);
+ visitArgumentBuffers(heapRootVisitor);
+ visitException(heapRootVisitor);
+ visitStrongHandles(heapRootVisitor);
+ visitHandleStack(heapRootVisitor);
+ traceCodeBlocksAndJITStubRoutines();
+ converge();
+ }
- {
- GCPHASE(VisitMachineRoots);
- MARK_LOG_ROOT(visitor, "C++ Stack");
- visitor.append(machineThreadRoots);
- visitor.donateAndDrain();
- }
+ // Weak references must be marked last because their liveness depends on
+ // the liveness of the rest of the object graph.
+ visitWeakHandles(heapRootVisitor);
+
+ clearRememberedSet(rememberedSet);
+ m_sharedData.didFinishMarking();
+ updateObjectCounts();
+ resetVisitors();
+}
+
+void Heap::copyBackingStores()
+{
+ if (m_operationInProgress == EdenCollection)
+ m_storageSpace.startedCopying<EdenCollection>();
+ else {
+ ASSERT(m_operationInProgress == FullCollection);
+ m_storageSpace.startedCopying<FullCollection>();
+ }
+
+ if (m_storageSpace.shouldDoCopyPhase()) {
+ m_sharedData.didStartCopying();
+ 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();
+ } else
+ m_storageSpace.doneCopying();
+}
+
+void Heap::gatherStackRoots(ConservativeRoots& roots, void** dummy)
+{
+ GCPHASE(GatherStackRoots);
+ m_jitStubRoutines.clearMarks();
+ m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, dummy);
+}
+
+void Heap::gatherJSStackRoots(ConservativeRoots& roots)
+{
#if ENABLE(LLINT_C_LOOP)
- {
- GCPHASE(VisitStackRoots);
- MARK_LOG_ROOT(visitor, "Stack");
- visitor.append(stackRoots);
- visitor.donateAndDrain();
- }
+ GCPHASE(GatherStackRoots);
+ stack().gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks);
+#else
+ UNUSED_PARAM(roots);
#endif
+}
+
+void Heap::gatherScratchBufferRoots(ConservativeRoots& roots)
+{
#if ENABLE(DFG_JIT)
- {
- GCPHASE(VisitScratchBufferRoots);
- MARK_LOG_ROOT(visitor, "Scratch Buffers");
- visitor.append(scratchBufferRoots);
- visitor.donateAndDrain();
- }
- {
- GCPHASE(VisitDFGWorklists);
- MARK_LOG_ROOT(visitor, "DFG Worklists");
- for (unsigned i = DFG::numberOfWorklists(); i--;) {
- if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
- worklist->visitChildren(visitor, m_codeBlocks);
- }
- }
+ GCPHASE(GatherScratchBufferRoots);
+ m_vm->gatherConservativeRoots(roots);
+#else
+ UNUSED_PARAM(roots);
#endif
- {
- GCPHASE(VisitProtectedObjects);
- MARK_LOG_ROOT(visitor, "Protected Objects");
- markProtectedObjects(heapRootVisitor);
- visitor.donateAndDrain();
+}
+
+void Heap::clearLivenessData()
+{
+ GCPHASE(ClearLivenessData);
+ m_objectSpace.clearNewlyAllocated();
+ m_objectSpace.clearMarks();
+}
+
+void Heap::visitSmallStrings()
+{
+ GCPHASE(VisitSmallStrings);
+ m_vm->smallStrings.visitStrongReferences(m_slotVisitor);
+}
+
+void Heap::visitConservativeRoots(ConservativeRoots& roots)
+{
+ GCPHASE(VisitConservativeRoots);
+ MARK_LOG_ROOT(m_slotVisitor, "Conservative Roots");
+ m_slotVisitor.append(roots);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitCompilerWorklists()
+{
+#if ENABLE(DFG_JIT)
+ GCPHASE(VisitDFGWorklists);
+ MARK_LOG_ROOT(m_slotVisitor, "DFG Worklists");
+ for (unsigned i = DFG::numberOfWorklists(); i--;) {
+ if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
+ worklist->visitChildren(m_slotVisitor, m_codeBlocks);
+ }
+#endif
+}
+
+void Heap::visitProtectedObjects(HeapRootVisitor& heapRootVisitor)
+{
+ GCPHASE(VisitProtectedObjects);
+ MARK_LOG_ROOT(m_slotVisitor, "Protected Objects");
+ ProtectCountSet::iterator end = m_protectedValues.end();
+ for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
+ heapRootVisitor.visit(&it->key);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitTempSortVectors(HeapRootVisitor& heapRootVisitor)
+{
+ GCPHASE(VisitTempSortVectors);
+ MARK_LOG_ROOT(m_slotVisitor, "Temp Sort Vectors");
+
+ typedef Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>* > VectorOfValueStringVectors;
+
+ VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
+ for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
+ Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempSortingVector = *it;
+
+ Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
+ for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
+ if (vectorIt->first)
+ heapRootVisitor.visit(&vectorIt->first);
}
- {
- GCPHASE(VisitTempSortVectors);
- MARK_LOG_ROOT(visitor, "Temp Sort Vectors");
- markTempSortVectors(heapRootVisitor);
- visitor.donateAndDrain();
- }
+ }
+ m_slotVisitor.donateAndDrain();
+}
- {
- GCPHASE(MarkingArgumentBuffers);
- if (m_markListSet && m_markListSet->size()) {
- MARK_LOG_ROOT(visitor, "Argument Buffers");
- MarkedArgumentBuffer::markLists(heapRootVisitor, *m_markListSet);
- visitor.donateAndDrain();
- }
- }
- if (m_vm->exception()) {
- GCPHASE(MarkingException);
- MARK_LOG_ROOT(visitor, "Exceptions");
- heapRootVisitor.visit(m_vm->addressOfException());
- visitor.donateAndDrain();
- }
-
- {
- GCPHASE(VisitStrongHandles);
- MARK_LOG_ROOT(visitor, "Strong Handles");
- m_handleSet.visitStrongHandles(heapRootVisitor);
- visitor.donateAndDrain();
- }
-
- {
- GCPHASE(HandleStack);
- MARK_LOG_ROOT(visitor, "Handle Stack");
- m_handleStack.visit(heapRootVisitor);
- visitor.donateAndDrain();
- }
-
- {
- GCPHASE(TraceCodeBlocksAndJITStubRoutines);
- MARK_LOG_ROOT(visitor, "Trace Code Blocks and JIT Stub Routines");
- m_codeBlocks.traceMarked(visitor);
- m_jitStubRoutines.traceMarkedStubRoutines(visitor);
- visitor.donateAndDrain();
- }
-
+void Heap::visitArgumentBuffers(HeapRootVisitor& visitor)
+{
+ GCPHASE(MarkingArgumentBuffers);
+ MARK_LOG_ROOT(m_slotVisitor, "Argument Buffers");
+ if (!m_markListSet || !m_markListSet->size())
+ return;
+
+ MarkedArgumentBuffer::markLists(visitor, *m_markListSet);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitException(HeapRootVisitor& visitor)
+{
+ GCPHASE(MarkingException);
+ MARK_LOG_ROOT(m_slotVisitor, "Exceptions");
+ if (!m_vm->exception())
+ return;
+
+ visitor.visit(m_vm->addressOfException());
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitStrongHandles(HeapRootVisitor& visitor)
+{
+ GCPHASE(VisitStrongHandles);
+ MARK_LOG_ROOT(m_slotVisitor, "Strong Handles");
+ m_handleSet.visitStrongHandles(visitor);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitHandleStack(HeapRootVisitor& visitor)
+{
+ GCPHASE(VisitHandleStack);
+ MARK_LOG_ROOT(m_slotVisitor, "Handle Stack");
+ m_handleStack.visit(visitor);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::traceCodeBlocksAndJITStubRoutines()
+{
+ GCPHASE(TraceCodeBlocksAndJITStubRoutines);
+ MARK_LOG_ROOT(m_slotVisitor, "Trace Code Blocks and JIT Stub Routines");
+ m_codeBlocks.traceMarked(m_slotVisitor);
+ m_jitStubRoutines.traceMarkedStubRoutines(m_slotVisitor);
+ m_slotVisitor.donateAndDrain();
+}
+
+void Heap::converge()
+{
#if ENABLE(PARALLEL_GC)
- {
- GCPHASE(Convergence);
- visitor.drainFromShared(SlotVisitor::MasterDrain);
- }
+ GCPHASE(Convergence);
+ m_slotVisitor.drainFromShared(SlotVisitor::MasterDrain);
#endif
- }
+}
- // Weak references must be marked last because their liveness depends on
- // the liveness of the rest of the object graph.
- {
- GCPHASE(VisitingLiveWeakHandles);
- MARK_LOG_ROOT(visitor, "Live Weak Handles");
- while (true) {
- m_objectSpace.visitWeakSets(heapRootVisitor);
- harvestWeakReferences();
- if (visitor.isEmpty())
- break;
- {
- ParallelModeEnabler enabler(visitor);
- visitor.donateAndDrain();
+void Heap::visitWeakHandles(HeapRootVisitor& visitor)
+{
+ GCPHASE(VisitingLiveWeakHandles);
+ MARK_LOG_ROOT(m_slotVisitor, "Live Weak Handles");
+ while (true) {
+ m_objectSpace.visitWeakSets(visitor);
+ harvestWeakReferences();
+ if (m_slotVisitor.isEmpty())
+ break;
+ {
+ ParallelModeEnabler enabler(m_slotVisitor);
+ m_slotVisitor.donateAndDrain();
#if ENABLE(PARALLEL_GC)
- visitor.drainFromShared(SlotVisitor::MasterDrain);
+ m_slotVisitor.drainFromShared(SlotVisitor::MasterDrain);
#endif
- }
}
}
+}
+void Heap::clearRememberedSet(Vector<const JSCell*>& rememberedSet)
+{
#if ENABLE(GGC)
- {
- GCPHASE(ClearRememberedSet);
- for (unsigned i = 0; i < rememberedSet.size(); ++i) {
- const JSCell* cell = rememberedSet[i];
- MarkedBlock::blockFor(cell)->clearRemembered(cell);
- }
+ GCPHASE(ClearRememberedSet);
+ for (unsigned i = 0; i < rememberedSet.size(); ++i) {
+ const JSCell* cell = rememberedSet[i];
+ MarkedBlock::blockFor(cell)->clearRemembered(cell);
}
+#else
+ UNUSED_PARAM(rememberedSet);
#endif
+}
- GCCOUNTER(VisitedValueCount, visitor.visitCount());
+void Heap::updateObjectCounts()
+{
+ GCCOUNTER(VisitedValueCount, m_slotVisitor.visitCount());
- m_sharedData.didFinishMarking();
#if ENABLE(OBJECT_MARK_LOGGING)
- size_t visitCount = visitor.visitCount();
+ size_t visitCount = m_slotVisitor.visitCount();
#if ENABLE(PARALLEL_GC)
visitCount += m_sharedData.childVisitCount();
#endif
@@ -634,42 +692,28 @@
#endif
if (m_operationInProgress == EdenCollection) {
- m_totalBytesVisited += visitor.bytesVisited();
- m_totalBytesCopied += visitor.bytesCopied();
+ m_totalBytesVisited += m_slotVisitor.bytesVisited();
+ m_totalBytesCopied += m_slotVisitor.bytesCopied();
} else {
ASSERT(m_operationInProgress == FullCollection);
- m_totalBytesVisited = visitor.bytesVisited();
- m_totalBytesCopied = visitor.bytesCopied();
+ m_totalBytesVisited = m_slotVisitor.bytesVisited();
+ m_totalBytesCopied = m_slotVisitor.bytesCopied();
}
#if ENABLE(PARALLEL_GC)
m_totalBytesVisited += m_sharedData.childBytesVisited();
m_totalBytesCopied += m_sharedData.childBytesCopied();
#endif
+}
- visitor.reset();
+void Heap::resetVisitors()
+{
+ m_slotVisitor.reset();
#if ENABLE(PARALLEL_GC)
m_sharedData.resetChildren();
#endif
m_sharedData.reset();
}
-template <HeapOperation collectionType>
-void Heap::copyBackingStores()
-{
- m_storageSpace.startedCopying<collectionType>();
- if (m_storageSpace.shouldDoCopyPhase()) {
- m_sharedData.didStartCopying();
- 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();
- } else
- m_storageSpace.doneCopying();
-}
-
size_t Heap::objectCount()
{
return m_objectSpace.objectCount();
@@ -762,6 +806,7 @@
void Heap::deleteUnmarkedCompiledCode()
{
+ GCPHASE(DeleteCodeBlocks);
ExecutableBase* next;
for (ExecutableBase* current = m_compiledCode.head(); current; current = next) {
next = current->next();
@@ -825,14 +870,70 @@
ASSERT(m_isSafeToCollect);
_javascript_CORE_GC_BEGIN();
RELEASE_ASSERT(m_operationInProgress == NoOperation);
-
+
+ suspendCompilerThreads();
+ willStartCollection();
+
+ double gcStartTime = WTF::monotonicallyIncreasingTime();
+
+ deleteOldCode(gcStartTime);
+ flushOldStructureIDTables();
+ stopAllocation();
+ flushWriteBarrierBuffer();
+
+ markRoots();
+
+ _javascript_CORE_GC_MARKED();
+
+ reapWeakHandles();
+ sweepArrayBuffers();
+ snapshotMarkedSpace();
+
+ copyBackingStores();
+
+ finalizeUnconditionalFinalizers();
+ deleteUnmarkedCompiledCode();
+ deleteSourceProviderCaches();
+ notifyIncrementalSweeper();
+ rememberCurrentlyExecutingCodeBlocks();
+
+ resetAllocators();
+ updateAllocationLimits();
+ didFinishCollection(gcStartTime);
+ resumeCompilerThreads();
+
+ if (Options::logGC()) {
+ double after = currentTimeMS();
+ dataLog(after - before, " ms]\n");
+ }
+}
+
+bool Heap::collectIfNecessaryOrDefer()
+{
+ if (isDeferred())
+ return false;
+
+ if (!shouldCollect())
+ return false;
+
+ collect();
+ return true;
+}
+
+void Heap::suspendCompilerThreads()
+{
#if ENABLE(DFG_JIT)
+ GCPHASE(SuspendCompilerThreads);
for (unsigned i = DFG::numberOfWorklists(); i--;) {
if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
worklist->suspendAllThreads();
}
#endif
+}
+void Heap::willStartCollection()
+{
+ GCPHASE(StartingCollection);
if (shouldDoFullCollection()) {
m_operationInProgress = FullCollection;
m_slotVisitor.clearMarkStack();
@@ -849,84 +950,93 @@
if (m_activityCallback)
m_activityCallback->willCollect();
+}
- double lastGCStartTime = WTF::monotonicallyIncreasingTime();
- if (lastGCStartTime - m_lastCodeDiscardTime > minute) {
+void Heap::deleteOldCode(double gcStartTime)
+{
+ GCPHASE(DeleteOldCode);
+ if (gcStartTime - m_lastCodeDiscardTime > minute) {
deleteAllCompiledCode();
m_lastCodeDiscardTime = WTF::monotonicallyIncreasingTime();
}
+}
- {
- GCPHASE(StopAllocation);
- m_structureIDTable.flushOldTables();
- m_objectSpace.stopAllocating();
- if (m_operationInProgress == FullCollection)
- m_storageSpace.didStartFullCollection();
- }
+void Heap::flushOldStructureIDTables()
+{
+ GCPHASE(FlushOldStructureIDTables);
+ m_structureIDTable.flushOldTables();
+}
- {
- GCPHASE(FlushWriteBarrierBuffer);
- if (m_operationInProgress == EdenCollection)
- m_writeBarrierBuffer.flush(*this);
- else
- m_writeBarrierBuffer.reset();
+void Heap::flushWriteBarrierBuffer()
+{
+ GCPHASE(FlushWriteBarrierBuffer);
+ if (m_operationInProgress == EdenCollection) {
+ m_writeBarrierBuffer.flush(*this);
+ return;
}
+ m_writeBarrierBuffer.reset();
+}
- markRoots();
-
- {
- GCPHASE(ReapingWeakHandles);
- m_objectSpace.reapWeakSets();
- }
+void Heap::stopAllocation()
+{
+ GCPHASE(StopAllocation);
+ m_objectSpace.stopAllocating();
+ if (m_operationInProgress == FullCollection)
+ m_storageSpace.didStartFullCollection();
+}
- _javascript_CORE_GC_MARKED();
-
- {
- GCPHASE(SweepingArrayBuffers);
- m_arrayBuffers.sweep();
- }
+void Heap::reapWeakHandles()
+{
+ GCPHASE(ReapingWeakHandles);
+ m_objectSpace.reapWeakSets();
+}
- if (m_operationInProgress == FullCollection) {
- m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
- MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
- m_objectSpace.forEachBlock(functor);
- }
+void Heap::sweepArrayBuffers()
+{
+ GCPHASE(SweepingArrayBuffers);
+ m_arrayBuffers.sweep();
+}
- if (m_operationInProgress == FullCollection)
- copyBackingStores<FullCollection>();
- else
- copyBackingStores<EdenCollection>();
+void Heap::snapshotMarkedSpace()
+{
+ GCPHASE(SnapshotMarkedSpace);
+ if (m_operationInProgress != FullCollection)
+ return;
- {
- GCPHASE(FinalizeUnconditionalFinalizers);
- finalizeUnconditionalFinalizers();
- }
+ m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
+ MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
+ m_objectSpace.forEachBlock(functor);
+}
- {
- GCPHASE(DeleteCodeBlocks);
- deleteUnmarkedCompiledCode();
- }
+void Heap::deleteSourceProviderCaches()
+{
+ GCPHASE(DeleteSourceProviderCaches);
+ m_vm->clearSourceProviderCaches();
+}
- {
- GCPHASE(DeleteSourceProviderCaches);
- m_vm->clearSourceProviderCaches();
- }
+void Heap::notifyIncrementalSweeper()
+{
+ GCPHASE(NotifyIncrementalSweeper);
+ if (m_operationInProgress != FullCollection)
+ return;
+ m_sweeper->startSweeping(m_blockSnapshot);
+}
- if (m_operationInProgress == FullCollection)
- m_sweeper->startSweeping(m_blockSnapshot);
+void Heap::rememberCurrentlyExecutingCodeBlocks()
+{
+ GCPHASE(RememberCurrentlyExecutingCodeBlocks);
+ m_codeBlocks.rememberCurrentlyExecutingCodeBlocks(this);
+}
- {
- GCPHASE(AddCurrentlyExecutingCodeBlocksToRememberedSet);
- m_codeBlocks.rememberCurrentlyExecutingCodeBlocks(this);
- }
+void Heap::resetAllocators()
+{
+ GCPHASE(ResetAllocators);
+ m_objectSpace.resetAllocators();
+}
- m_bytesAbandonedThisCycle = 0;
-
- {
- GCPHASE(ResetAllocators);
- m_objectSpace.resetAllocators();
- }
-
+void Heap::updateAllocationLimits()
+{
+ GCPHASE(UpdateAllocationLimits);
size_t currentHeapSize = sizeAfterCollect();
if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize())
HeapStatistics::exitWithFailure();
@@ -949,13 +1059,21 @@
}
m_sizeAfterLastCollect = currentHeapSize;
-
m_bytesAllocatedThisCycle = 0;
- double lastGCEndTime = WTF::monotonicallyIncreasingTime();
- m_lastGCLength = lastGCEndTime - lastGCStartTime;
+ m_bytesAbandonedThisCycle = 0;
+ if (Options::logGC())
+ dataLog(currentHeapSize / 1024, " kb, ");
+}
+
+void Heap::didFinishCollection(double gcStartTime)
+{
+ GCPHASE(FinishingCollection);
+ double gcEndTime = WTF::monotonicallyIncreasingTime();
+ m_lastGCLength = gcEndTime - gcStartTime;
+
if (Options::recordGCPauseTimes())
- HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime);
+ HeapStatistics::recordGCPauseTime(gcStartTime, gcEndTime);
RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
m_operationInProgress = NoOperation;
@@ -969,32 +1087,19 @@
if (Options::showObjectStatistics())
HeapStatistics::showObjectStatistics(this);
-
+}
+
+void Heap::resumeCompilerThreads()
+{
#if ENABLE(DFG_JIT)
+ GCPHASE(ResumeCompilerThreads);
for (unsigned i = DFG::numberOfWorklists(); i--;) {
if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
worklist->resumeAllThreads();
}
#endif
-
- if (Options::logGC()) {
- double after = currentTimeMS();
- dataLog(after - before, " ms, ", currentHeapSize / 1024, " kb]\n");
- }
}
-bool Heap::collectIfNecessaryOrDefer()
-{
- if (isDeferred())
- return false;
-
- if (!shouldCollect())
- return false;
-
- collect();
- return true;
-}
-
void Heap::markDeadObjects()
{
HeapIterationScope iterationScope(*this);