diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/Heap.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/Heap.cpp | 174 |
1 files changed, 55 insertions, 119 deletions
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index ca936ebfc..772d85144 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -21,12 +21,14 @@ #include "config.h" #include "Heap.h" -#include "CopiedSpace.h" -#include "CopiedSpaceInlineMethods.h" #include "CodeBlock.h" #include "ConservativeRoots.h" +#include "CopiedSpace.h" +#include "CopiedSpaceInlineMethods.h" +#include "CopyVisitorInlineMethods.h" #include "GCActivityCallback.h" #include "HeapRootVisitor.h" +#include "HeapStatistics.h" #include "IncrementalSweeper.h" #include "Interpreter.h" #include "JSGlobalData.h" @@ -235,74 +237,6 @@ inline PassOwnPtr<TypeCountSet> RecordType::returnValue() return m_typeCountSet.release(); } -class StorageStatistics : public MarkedBlock::VoidFunctor { -public: - StorageStatistics(); - - void operator()(JSCell*); - - size_t objectWithOutOfLineStorageCount(); - size_t objectCount(); - - size_t storageSize(); - size_t storageCapacity(); - -private: - size_t m_objectWithOutOfLineStorageCount; - size_t m_objectCount; - size_t m_storageSize; - size_t m_storageCapacity; -}; - -inline StorageStatistics::StorageStatistics() - : m_objectWithOutOfLineStorageCount(0) - , m_objectCount(0) - , m_storageSize(0) - , m_storageCapacity(0) -{ -} - -inline void StorageStatistics::operator()(JSCell* cell) -{ - if (!cell->isObject()) - return; - - JSObject* object = jsCast<JSObject*>(cell); - if (hasIndexedProperties(object->structure()->indexingType())) - return; - - if (object->structure()->isUncacheableDictionary()) - return; - - ++m_objectCount; - if (!object->hasInlineStorage()) - ++m_objectWithOutOfLineStorageCount; - m_storageSize += object->structure()->totalStorageSize() * sizeof(WriteBarrierBase<Unknown>); - m_storageCapacity += object->structure()->totalStorageCapacity() * sizeof(WriteBarrierBase<Unknown>); -} - -inline size_t StorageStatistics::objectWithOutOfLineStorageCount() -{ - return m_objectWithOutOfLineStorageCount; -} - -inline size_t StorageStatistics::objectCount() -{ - return m_objectCount; -} - - -inline size_t StorageStatistics::storageSize() -{ - return m_storageSize; -} - - -inline size_t StorageStatistics::storageCapacity() -{ - return m_storageCapacity; -} - } // anonymous namespace Heap::Heap(JSGlobalData* globalData, HeapType heapType) @@ -319,6 +253,7 @@ Heap::Heap(JSGlobalData* globalData, HeapType heapType) , m_machineThreads(this) , m_sharedData(globalData) , m_slotVisitor(m_sharedData) + , m_copyVisitor(m_sharedData) , m_handleSet(globalData) , m_isSafeToCollect(false) , m_globalData(globalData) @@ -422,7 +357,7 @@ void Heap::markProtectedObjects(HeapRootVisitor& heapRootVisitor) { ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) - heapRootVisitor.visit(&it->first); + heapRootVisitor.visit(&it->key); } void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector) @@ -462,19 +397,19 @@ void Heap::finalizeUnconditionalFinalizers() m_slotVisitor.finalizeUnconditionalFinalizers(); } -inline RegisterFile& Heap::registerFile() +inline JSStack& Heap::stack() { - return m_globalData->interpreter->registerFile(); + return m_globalData->interpreter->stack(); } void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots) { ASSERT(isValidThreadState(m_globalData)); - ConservativeRoots registerFileRoots(&m_objectSpace.blocks(), &m_storageSpace); - registerFile().gatherConservativeRoots(registerFileRoots); - size_t registerFileRootCount = registerFileRoots.size(); - JSCell** registerRoots = registerFileRoots.roots(); - for (size_t i = 0; i < registerFileRootCount; i++) { + ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace); + stack().gatherConservativeRoots(stackRoots); + size_t stackRootCount = stackRoots.size(); + JSCell** registerRoots = stackRoots.roots(); + for (size_t i = 0; i < stackRootCount; i++) { setMarked(registerRoots[i]); roots.add(registerRoots[i]); } @@ -503,12 +438,12 @@ void Heap::markRoots(bool fullGC) m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy); } - ConservativeRoots registerFileRoots(&m_objectSpace.blocks(), &m_storageSpace); + ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace); m_dfgCodeBlocks.clearMarks(); { - GCPHASE(GatherRegisterFileRoots); - registerFile().gatherConservativeRoots( - registerFileRoots, m_jitStubRoutines, m_dfgCodeBlocks); + GCPHASE(GatherStackRoots); + stack().gatherConservativeRoots( + stackRoots, m_jitStubRoutines, m_dfgCodeBlocks); } #if ENABLE(DFG_JIT) @@ -531,7 +466,7 @@ void Heap::markRoots(bool fullGC) m_objectSpace.clearMarks(); } - m_storageSpace.startedCopying(); + m_sharedData.didStartMarking(); SlotVisitor& visitor = m_slotVisitor; visitor.setup(); HeapRootVisitor heapRootVisitor(visitor); @@ -563,9 +498,9 @@ void Heap::markRoots(bool fullGC) visitor.donateAndDrain(); } { - GCPHASE(VisitRegisterFileRoots); - MARK_LOG_ROOT(visitor, "Register File"); - visitor.append(registerFileRoots); + GCPHASE(VisitStackRoots); + MARK_LOG_ROOT(visitor, "Stack"); + visitor.append(stackRoots); visitor.donateAndDrain(); } #if ENABLE(DFG_JIT) @@ -656,7 +591,7 @@ void Heap::markRoots(bool fullGC) GCCOUNTER(VisitedValueCount, visitor.visitCount()); - visitor.doneCopying(); + m_sharedData.didFinishMarking(); #if ENABLE(OBJECT_MARK_LOGGING) size_t visitCount = visitor.visitCount(); #if ENABLE(PARALLEL_GC) @@ -670,7 +605,23 @@ void Heap::markRoots(bool fullGC) m_sharedData.resetChildren(); #endif m_sharedData.reset(); - m_storageSpace.doneCopying(); +} + +void Heap::copyBackingStores() +{ + m_storageSpace.startedCopying(); + if (m_storageSpace.shouldDoCopyPhase()) { + m_sharedData.didStartCopying(); + CopyVisitor& visitor = m_copyVisitor; + 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(); + } else + m_storageSpace.doneCopying(); } size_t Heap::objectCount() @@ -801,6 +752,14 @@ void Heap::collect(SweepToggle sweepToggle) JAVASCRIPTCORE_GC_MARKED(); { + m_blockSnapshot.resize(m_objectSpace.blocks().set().size()); + MarkedBlockSnapshotFunctor functor(m_blockSnapshot); + m_objectSpace.forEachBlock(functor); + } + + copyBackingStores(); + + { GCPHASE(FinalizeUnconditionalFinalizers); finalizeUnconditionalFinalizers(); } @@ -822,7 +781,7 @@ void Heap::collect(SweepToggle sweepToggle) m_objectSpace.shrink(); } - m_sweeper->startSweeping(m_objectSpace.blocks().set()); + m_sweeper->startSweeping(m_blockSnapshot); m_bytesAbandoned = 0; { @@ -831,6 +790,9 @@ void Heap::collect(SweepToggle sweepToggle) } size_t currentHeapSize = size(); + if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize()) + HeapStatistics::exitWithFailure(); + if (fullGC) { m_sizeAfterLastCollect = currentHeapSize; @@ -844,6 +806,8 @@ void Heap::collect(SweepToggle sweepToggle) double lastGCEndTime = WTF::currentTime(); m_lastGCLength = lastGCEndTime - lastGCStartTime; + if (Options::recordGCPauseTimes()) + HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime); if (m_operationInProgress != Collection) CRASH(); m_operationInProgress = NoOperation; @@ -855,31 +819,8 @@ void Heap::collect(SweepToggle sweepToggle) if (Options::objectsAreImmortal()) markDeadObjects(); - if (Options::showHeapStatistics()) - showStatistics(); -} - -void Heap::showStatistics() -{ - dataLog("\n=== Heap Statistics: ===\n"); - dataLog("size: %ldkB\n", static_cast<long>(m_sizeAfterLastCollect / KB)); - dataLog("capacity: %ldkB\n", static_cast<long>(capacity() / KB)); - dataLog("pause time: %lfms\n\n", m_lastGCLength); - - StorageStatistics storageStatistics; - m_objectSpace.forEachLiveCell(storageStatistics); - dataLog("wasted .property storage: %ldkB (%ld%%)\n", - static_cast<long>( - (storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB), - static_cast<long>( - (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100 - / storageStatistics.storageCapacity())); - dataLog("objects with out-of-line .property storage: %ld (%ld%%)\n", - static_cast<long>( - storageStatistics.objectWithOutOfLineStorageCount()), - static_cast<long>( - storageStatistics.objectWithOutOfLineStorageCount() * 100 - / storageStatistics.objectCount())); + if (Options::showObjectStatistics()) + HeapStatistics::showObjectStatistics(this); } void Heap::markDeadObjects() @@ -942,11 +883,6 @@ void Heap::addCompiledCode(ExecutableBase* executable) m_compiledCode.append(executable); } -bool Heap::isSafeToSweepStructures() -{ - return !m_sweeper || m_sweeper->structuresCanBeSwept(); -} - void Heap::didStartVMShutdown() { m_activityCallback->didStartVMShutdown(); |