summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/Heap.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
commit49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch)
tree5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/JavaScriptCore/heap/Heap.cpp
parentb211c645d8ab690f713515dfdc84d80b11c27d2c (diff)
downloadqtwebkit-49233e234e5c787396cadb2cea33b31ae0cd65c1.tar.gz
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/JavaScriptCore/heap/Heap.cpp')
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp97
1 files changed, 69 insertions, 28 deletions
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 90c4bb72c..ef062c9ce 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -245,8 +245,6 @@ Heap::Heap(JSGlobalData* globalData, HeapType heapType)
, m_operationInProgress(NoOperation)
, m_objectSpace(this)
, m_storageSpace(this)
- , m_activityCallback(DefaultGCActivityCallback::create(this))
- , m_sweeper(IncrementalSweeper::create(this))
, m_machineThreads(this)
, m_sharedData(globalData)
, m_slotVisitor(m_sharedData)
@@ -255,6 +253,8 @@ Heap::Heap(JSGlobalData* globalData, HeapType heapType)
, m_globalData(globalData)
, m_lastGCLength(0)
, m_lastCodeDiscardTime(WTF::currentTime())
+ , m_activityCallback(DefaultGCActivityCallback::create(this))
+ , m_sweeper(IncrementalSweeper::create(this))
{
m_storageSpace.init();
}
@@ -403,9 +403,6 @@ inline RegisterFile& Heap::registerFile()
void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
{
ASSERT(isValidThreadState(m_globalData));
- if (m_operationInProgress != NoOperation)
- CRASH();
- m_operationInProgress = Collection;
ConservativeRoots registerFileRoots(&m_objectSpace.blocks(), &m_storageSpace);
registerFile().gatherConservativeRoots(registerFileRoots);
size_t registerFileRootCount = registerFileRoots.size();
@@ -414,7 +411,6 @@ void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
setMarked(registerRoots[i]);
roots.add(registerRoots[i]);
}
- m_operationInProgress = NoOperation;
}
void Heap::markRoots(bool fullGC)
@@ -424,9 +420,10 @@ void Heap::markRoots(bool fullGC)
COND_GCPHASE(fullGC, MarkFullRoots, MarkYoungRoots);
UNUSED_PARAM(fullGC);
ASSERT(isValidThreadState(m_globalData));
- if (m_operationInProgress != NoOperation)
- CRASH();
- m_operationInProgress = Collection;
+
+#if ENABLE(OBJECT_MARK_LOGGING)
+ double gcStartTime = WTF::currentTime();
+#endif
void* dummy;
@@ -491,28 +488,33 @@ void Heap::markRoots(bool fullGC)
{
GCPHASE(VisitMachineRoots);
+ MARK_LOG_ROOT(visitor, "C++ Stack");
visitor.append(machineThreadRoots);
visitor.donateAndDrain();
}
{
GCPHASE(VisitRegisterFileRoots);
+ MARK_LOG_ROOT(visitor, "Register File");
visitor.append(registerFileRoots);
visitor.donateAndDrain();
}
#if ENABLE(DFG_JIT)
{
GCPHASE(VisitScratchBufferRoots);
+ MARK_LOG_ROOT(visitor, "Scratch Buffers");
visitor.append(scratchBufferRoots);
visitor.donateAndDrain();
}
#endif
{
GCPHASE(VisitProtectedObjects);
+ MARK_LOG_ROOT(visitor, "Protected Objects");
markProtectedObjects(heapRootVisitor);
visitor.donateAndDrain();
}
{
GCPHASE(VisitTempSortVectors);
+ MARK_LOG_ROOT(visitor, "Temp Sort Vectors");
markTempSortVectors(heapRootVisitor);
visitor.donateAndDrain();
}
@@ -520,30 +522,35 @@ void Heap::markRoots(bool fullGC)
{
GCPHASE(MarkingArgumentBuffers);
if (m_markListSet && m_markListSet->size()) {
+ MARK_LOG_ROOT(visitor, "Argument Buffers");
MarkedArgumentBuffer::markLists(heapRootVisitor, *m_markListSet);
visitor.donateAndDrain();
}
}
if (m_globalData->exception) {
GCPHASE(MarkingException);
+ MARK_LOG_ROOT(visitor, "Exceptions");
heapRootVisitor.visit(&m_globalData->exception);
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(TraceCodeBlocks);
+ MARK_LOG_ROOT(visitor, "Trace Code Blocks");
m_dfgCodeBlocks.traceMarkedCodeBlocks(visitor);
visitor.donateAndDrain();
}
@@ -560,6 +567,7 @@ void Heap::markRoots(bool fullGC)
// 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();
@@ -578,11 +586,21 @@ void Heap::markRoots(bool fullGC)
GCCOUNTER(VisitedValueCount, visitor.visitCount());
visitor.doneCopying();
+#if ENABLE(OBJECT_MARK_LOGGING)
+ size_t visitCount = visitor.visitCount();
+#if ENABLE(PARALLEL_GC)
+ visitCount += m_sharedData.childVisitCount();
+#endif
+ MARK_LOG_MESSAGE2("\nNumber of live Objects after full GC %lu, took %.6f secs\n", visitCount, WTF::currentTime() - gcStartTime);
+#endif
+
visitor.reset();
m_sharedData.reset();
+#if ENABLE(PARALLEL_GC)
+ m_sharedData.resetChildren();
+#endif
m_storageSpace.doneCopying();
- m_operationInProgress = NoOperation;
}
size_t Heap::objectCount()
@@ -625,15 +643,38 @@ PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
return m_objectSpace.forEachCell<RecordType>();
}
-void Heap::discardAllCompiledCode()
+void Heap::deleteAllCompiledCode()
{
- // If JavaScript is running, it's not safe to recompile, since we'll end
- // up throwing away code that is live on the stack.
+ // If JavaScript is running, it's not safe to delete code, since we'll end
+ // up deleting code that is live on the stack.
if (m_globalData->dynamicGlobalObject)
return;
- for (FunctionExecutable* current = m_functions.head(); current; current = current->next())
- current->discardCode();
+ for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
+ if (!current->isFunctionExecutable())
+ continue;
+ static_cast<FunctionExecutable*>(current)->clearCodeIfNotCompiling();
+ }
+
+ m_dfgCodeBlocks.clearMarks();
+ m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
+}
+
+void Heap::deleteUnmarkedCompiledCode()
+{
+ ExecutableBase* next;
+ for (ExecutableBase* current = m_compiledCode.head(); current; current = next) {
+ next = current->next();
+ if (isMarked(current))
+ continue;
+
+ // We do this because executable memory is limited on some platforms and because
+ // CodeBlock requires eager finalization.
+ ExecutableBase::clearCodeVirtual(current);
+ m_compiledCode.remove(current);
+ }
+
+ m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
}
void Heap::collectAllGarbage()
@@ -654,12 +695,15 @@ void Heap::collect(SweepToggle sweepToggle)
ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
ASSERT(m_isSafeToCollect);
JAVASCRIPTCORE_GC_BEGIN();
+ if (m_operationInProgress != NoOperation)
+ CRASH();
+ m_operationInProgress = Collection;
m_activityCallback->willCollect();
double lastGCStartTime = WTF::currentTime();
if (lastGCStartTime - m_lastCodeDiscardTime > minute) {
- discardAllCompiledCode();
+ deleteAllCompiledCode();
m_lastCodeDiscardTime = WTF::currentTime();
}
@@ -682,22 +726,21 @@ void Heap::collect(SweepToggle sweepToggle)
m_objectSpace.reapWeakSets();
}
+ JAVASCRIPTCORE_GC_MARKED();
+
{
GCPHASE(FinalizeUnconditionalFinalizers);
finalizeUnconditionalFinalizers();
}
{
- GCPHASE(FinalizeWeakHandles);
- m_objectSpace.sweepWeakSets();
+ GCPHASE(finalizeSmallStrings);
m_globalData->smallStrings.finalizeSmallStrings();
}
-
- JAVASCRIPTCORE_GC_MARKED();
{
GCPHASE(DeleteCodeBlocks);
- m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
+ deleteUnmarkedCompiledCode();
}
if (sweepToggle == DoSweep) {
@@ -728,6 +771,9 @@ void Heap::collect(SweepToggle sweepToggle)
m_bytesAllocated = 0;
double lastGCEndTime = WTF::currentTime();
m_lastGCLength = lastGCEndTime - lastGCStartTime;
+ if (m_operationInProgress != Collection)
+ CRASH();
+ m_operationInProgress = NoOperation;
JAVASCRIPTCORE_GC_END();
}
@@ -784,14 +830,9 @@ void Heap::FinalizerOwner::finalize(Handle<Unknown> handle, void* context)
WeakSet::deallocate(WeakImpl::asWeakImpl(slot));
}
-void Heap::addFunctionExecutable(FunctionExecutable* executable)
-{
- m_functions.append(executable);
-}
-
-void Heap::removeFunctionExecutable(FunctionExecutable* executable)
+void Heap::addCompiledCode(ExecutableBase* executable)
{
- m_functions.remove(executable);
+ m_compiledCode.append(executable);
}
} // namespace JSC