summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/Heap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap/Heap.cpp')
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp174
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();