<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164862] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164862">164862</a></dd>
<dt>Author</dt> <dd>mhahnenberg@apple.com</dd>
<dt>Date</dt> <dd>2014-02-28 08:56:17 -0800 (Fri, 28 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Clean up Heap::collect and Heap::markRoots
https://bugs.webkit.org/show_bug.cgi?id=129464

Reviewed by Geoffrey Garen.

These functions have built up a lot of cruft recently. 
We should do a bit of cleanup to make them easier to grok.

* heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):
(JSC::Heap::gatherStackRoots):
(JSC::Heap::gatherJSStackRoots):
(JSC::Heap::gatherScratchBufferRoots):
(JSC::Heap::clearLivenessData):
(JSC::Heap::visitSmallStrings):
(JSC::Heap::visitConservativeRoots):
(JSC::Heap::visitCompilerWorklists):
(JSC::Heap::markProtectedObjects):
(JSC::Heap::markTempSortVectors):
(JSC::Heap::markArgumentBuffers):
(JSC::Heap::visitException):
(JSC::Heap::visitStrongHandles):
(JSC::Heap::visitHandleStack):
(JSC::Heap::traceCodeBlocksAndJITStubRoutines):
(JSC::Heap::converge):
(JSC::Heap::visitWeakHandles):
(JSC::Heap::clearRememberedSet):
(JSC::Heap::updateObjectCounts):
(JSC::Heap::resetVisitors):
(JSC::Heap::markRoots):
(JSC::Heap::copyBackingStores):
(JSC::Heap::deleteUnmarkedCompiledCode):
(JSC::Heap::collect):
(JSC::Heap::collectIfNecessaryOrDefer):
(JSC::Heap::suspendCompilerThreads):
(JSC::Heap::willStartCollection):
(JSC::Heap::deleteOldCode):
(JSC::Heap::flushOldStructureIDTables):
(JSC::Heap::flushWriteBarrierBuffer):
(JSC::Heap::stopAllocation):
(JSC::Heap::reapWeakHandles):
(JSC::Heap::sweepArrayBuffers):
(JSC::Heap::snapshotMarkedSpace):
(JSC::Heap::deleteSourceProviderCaches):
(JSC::Heap::notifyIncrementalSweeper):
(JSC::Heap::rememberCurrentlyExecutingCodeBlocks):
(JSC::Heap::resetAllocators):
(JSC::Heap::updateAllocationLimits):
(JSC::Heap::didFinishCollection):
(JSC::Heap::resumeCompilerThreads):
* heap/Heap.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164861 => 164862)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-28 16:35:27 UTC (rev 164861)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-28 16:56:17 UTC (rev 164862)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2014-02-27  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
+
+        Clean up Heap::collect and Heap::markRoots
+        https://bugs.webkit.org/show_bug.cgi?id=129464
+
+        Reviewed by Geoffrey Garen.
+
+        These functions have built up a lot of cruft recently. 
+        We should do a bit of cleanup to make them easier to grok.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::finalizeUnconditionalFinalizers):
+        (JSC::Heap::gatherStackRoots):
+        (JSC::Heap::gatherJSStackRoots):
+        (JSC::Heap::gatherScratchBufferRoots):
+        (JSC::Heap::clearLivenessData):
+        (JSC::Heap::visitSmallStrings):
+        (JSC::Heap::visitConservativeRoots):
+        (JSC::Heap::visitCompilerWorklists):
+        (JSC::Heap::markProtectedObjects):
+        (JSC::Heap::markTempSortVectors):
+        (JSC::Heap::markArgumentBuffers):
+        (JSC::Heap::visitException):
+        (JSC::Heap::visitStrongHandles):
+        (JSC::Heap::visitHandleStack):
+        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
+        (JSC::Heap::converge):
+        (JSC::Heap::visitWeakHandles):
+        (JSC::Heap::clearRememberedSet):
+        (JSC::Heap::updateObjectCounts):
+        (JSC::Heap::resetVisitors):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::copyBackingStores):
+        (JSC::Heap::deleteUnmarkedCompiledCode):
+        (JSC::Heap::collect):
+        (JSC::Heap::collectIfNecessaryOrDefer):
+        (JSC::Heap::suspendCompilerThreads):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::deleteOldCode):
+        (JSC::Heap::flushOldStructureIDTables):
+        (JSC::Heap::flushWriteBarrierBuffer):
+        (JSC::Heap::stopAllocation):
+        (JSC::Heap::reapWeakHandles):
+        (JSC::Heap::sweepArrayBuffers):
+        (JSC::Heap::snapshotMarkedSpace):
+        (JSC::Heap::deleteSourceProviderCaches):
+        (JSC::Heap::notifyIncrementalSweeper):
+        (JSC::Heap::rememberCurrentlyExecutingCodeBlocks):
+        (JSC::Heap::resetAllocators):
+        (JSC::Heap::updateAllocationLimits):
+        (JSC::Heap::didFinishCollection):
+        (JSC::Heap::resumeCompilerThreads):
+        * heap/Heap.h:
+
</ins><span class="cx"> 2014-02-27  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         indexOf and lastIndexOf shouldn't resolve ropes when needle is longer than haystack
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (164861 => 164862)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-02-28 16:35:27 UTC (rev 164861)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-02-28 16:56:17 UTC (rev 164862)
</span><span class="lines">@@ -369,13 +369,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::markProtectedObjects(HeapRootVisitor&amp; heapRootVisitor)
-{
-    ProtectCountSet::iterator end = m_protectedValues.end();
-    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
-        heapRootVisitor.visit(&amp;it-&gt;key);
-}
-
</del><span class="cx"> void Heap::pushTempSortVector(Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* tempVector)
</span><span class="cx"> {
</span><span class="cx">     m_tempSortingVectors.append(tempVector);
</span><span class="lines">@@ -387,22 +380,6 @@
</span><span class="cx">     m_tempSortingVectors.removeLast();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::markTempSortVectors(HeapRootVisitor&amp; heapRootVisitor)
-{
-    typedef Vector&lt;Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* &gt; VectorOfValueStringVectors;
-
-    VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
-    for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
-        Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* tempSortingVector = *it;
-
-        Vector&lt;ValueStringPair&gt;::iterator vectorEnd = tempSortingVector-&gt;end();
-        for (Vector&lt;ValueStringPair&gt;::iterator vectorIt = tempSortingVector-&gt;begin(); vectorIt != vectorEnd; ++vectorIt) {
-            if (vectorIt-&gt;first)
-                heapRootVisitor.visit(&amp;vectorIt-&gt;first);
-        }
-    }
-}
-
</del><span class="cx"> void Heap::harvestWeakReferences()
</span><span class="cx"> {
</span><span class="cx">     m_slotVisitor.harvestWeakReferences();
</span><span class="lines">@@ -410,6 +387,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::finalizeUnconditionalFinalizers()
</span><span class="cx"> {
</span><ins>+    GCPHASE(FinalizeUnconditionalFinalizers);
</ins><span class="cx">     m_slotVisitor.finalizeUnconditionalFinalizers();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -444,7 +422,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::markRoots()
</span><span class="cx"> {
</span><del>-    SamplingRegion samplingRegion(&quot;Garbage Collection: Tracing&quot;);
</del><ins>+    SamplingRegion samplingRegion(&quot;Garbage Collection: Marking&quot;);
</ins><span class="cx"> 
</span><span class="cx">     GCPHASE(MarkRoots);
</span><span class="cx">     ASSERT(isValidThreadState(m_vm));
</span><span class="lines">@@ -454,45 +432,22 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     m_codeBlocks.clearMarks();
</span><del>-    void* dummy;
</del><span class="cx"> 
</span><span class="cx">     // We gather conservative roots before clearing mark bits because conservative
</span><span class="cx">     // gathering uses the mark bits to determine whether a reference is valid.
</span><del>-    ConservativeRoots machineThreadRoots(&amp;m_objectSpace.blocks(), &amp;m_storageSpace);
-    m_jitStubRoutines.clearMarks();
-    {
-        GCPHASE(GatherConservativeRoots);
-        m_machineThreads.gatherConservativeRoots(machineThreadRoots, m_jitStubRoutines, m_codeBlocks, &amp;dummy);
-    }
</del><ins>+    void* dummy;
+    ConservativeRoots conservativeRoots(&amp;m_objectSpace.blocks(), &amp;m_storageSpace);
+    gatherStackRoots(conservativeRoots, &amp;dummy);
+    gatherJSStackRoots(conservativeRoots);
+    gatherScratchBufferRoots(conservativeRoots);
</ins><span class="cx"> 
</span><del>-#if ENABLE(LLINT_C_LOOP)
-    ConservativeRoots stackRoots(&amp;m_objectSpace.blocks(), &amp;m_storageSpace);
-    {
-        GCPHASE(GatherStackRoots);
-        stack().gatherConservativeRoots(stackRoots, m_jitStubRoutines, m_codeBlocks);
-    }
-#endif
-
</del><span class="cx">     sanitizeStackForVM(m_vm);
</span><span class="cx"> 
</span><del>-#if ENABLE(DFG_JIT)
-    ConservativeRoots scratchBufferRoots(&amp;m_objectSpace.blocks(), &amp;m_storageSpace);
-    {
-        GCPHASE(GatherScratchBufferRoots);
-        m_vm-&gt;gatherConservativeRoots(scratchBufferRoots);
-    }
-#endif
</del><ins>+    clearLivenessData();
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(ClearLivenessData);
-        m_objectSpace.clearNewlyAllocated();
-        m_objectSpace.clearMarks();
-    }
-
</del><span class="cx">     m_sharedData.didStartMarking();
</span><del>-    SlotVisitor&amp; visitor = m_slotVisitor;
-    visitor.didStartMarking();
-    HeapRootVisitor heapRootVisitor(visitor);
</del><ins>+    m_slotVisitor.didStartMarking();
+    HeapRootVisitor heapRootVisitor(m_slotVisitor);
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(GGC)
</span><span class="cx">     Vector&lt;const JSCell*&gt; rememberedSet(m_slotVisitor.markStack().size());
</span><span class="lines">@@ -500,133 +455,236 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        ParallelModeEnabler enabler(visitor);
</del><ins>+        ParallelModeEnabler enabler(m_slotVisitor);
</ins><span class="cx"> 
</span><del>-        m_vm-&gt;smallStrings.visitStrongReferences(visitor);
</del><ins>+        visitSmallStrings();
+        visitConservativeRoots(conservativeRoots);
+        visitCompilerWorklists();
+        visitProtectedObjects(heapRootVisitor);
+        visitTempSortVectors(heapRootVisitor);
+        visitArgumentBuffers(heapRootVisitor);
+        visitException(heapRootVisitor);
+        visitStrongHandles(heapRootVisitor);
+        visitHandleStack(heapRootVisitor);
+        traceCodeBlocksAndJITStubRoutines();
+        converge();
+    }
</ins><span class="cx"> 
</span><del>-        {
-            GCPHASE(VisitMachineRoots);
-            MARK_LOG_ROOT(visitor, &quot;C++ Stack&quot;);
-            visitor.append(machineThreadRoots);
-            visitor.donateAndDrain();
-        }
</del><ins>+    // 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&lt;EdenCollection&gt;();
+    else {
+        ASSERT(m_operationInProgress == FullCollection);
+        m_storageSpace.startedCopying&lt;FullCollection&gt;();
+    }
+
+    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&amp; roots, void** dummy)
+{
+    GCPHASE(GatherStackRoots);
+    m_jitStubRoutines.clearMarks();
+    m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, dummy);
+}
+
+void Heap::gatherJSStackRoots(ConservativeRoots&amp; roots)
+{
</ins><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><del>-        {
-            GCPHASE(VisitStackRoots);
-            MARK_LOG_ROOT(visitor, &quot;Stack&quot;);
-            visitor.append(stackRoots);
-            visitor.donateAndDrain();
-        }
</del><ins>+    GCPHASE(GatherStackRoots);
+    stack().gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks);
+#else
+    UNUSED_PARAM(roots);
</ins><span class="cx"> #endif
</span><ins>+}
+
+void Heap::gatherScratchBufferRoots(ConservativeRoots&amp; roots)
+{
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><del>-        {
-            GCPHASE(VisitScratchBufferRoots);
-            MARK_LOG_ROOT(visitor, &quot;Scratch Buffers&quot;);
-            visitor.append(scratchBufferRoots);
-            visitor.donateAndDrain();
-        }
-        {
-            GCPHASE(VisitDFGWorklists);
-            MARK_LOG_ROOT(visitor, &quot;DFG Worklists&quot;);
-            for (unsigned i = DFG::numberOfWorklists(); i--;) {
-                if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
-                    worklist-&gt;visitChildren(visitor, m_codeBlocks);
-            }
-        }
</del><ins>+    GCPHASE(GatherScratchBufferRoots);
+    m_vm-&gt;gatherConservativeRoots(roots);
+#else
+    UNUSED_PARAM(roots);
</ins><span class="cx"> #endif
</span><del>-        {
-            GCPHASE(VisitProtectedObjects);
-            MARK_LOG_ROOT(visitor, &quot;Protected Objects&quot;);
-            markProtectedObjects(heapRootVisitor);
-            visitor.donateAndDrain();
</del><ins>+}
+
+void Heap::clearLivenessData()
+{
+    GCPHASE(ClearLivenessData);
+    m_objectSpace.clearNewlyAllocated();
+    m_objectSpace.clearMarks();
+}
+
+void Heap::visitSmallStrings()
+{
+    GCPHASE(VisitSmallStrings);
+    m_vm-&gt;smallStrings.visitStrongReferences(m_slotVisitor);
+}
+
+void Heap::visitConservativeRoots(ConservativeRoots&amp; roots)
+{
+    GCPHASE(VisitConservativeRoots);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Conservative Roots&quot;);
+    m_slotVisitor.append(roots);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitCompilerWorklists()
+{
+#if ENABLE(DFG_JIT)
+    GCPHASE(VisitDFGWorklists);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;DFG Worklists&quot;);
+    for (unsigned i = DFG::numberOfWorklists(); i--;) {
+        if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
+            worklist-&gt;visitChildren(m_slotVisitor, m_codeBlocks);
+    }
+#endif
+}
+
+void Heap::visitProtectedObjects(HeapRootVisitor&amp; heapRootVisitor)
+{
+    GCPHASE(VisitProtectedObjects);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Protected Objects&quot;);
+    ProtectCountSet::iterator end = m_protectedValues.end();
+    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
+        heapRootVisitor.visit(&amp;it-&gt;key);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitTempSortVectors(HeapRootVisitor&amp; heapRootVisitor)
+{
+    GCPHASE(VisitTempSortVectors);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Temp Sort Vectors&quot;);
+
+    typedef Vector&lt;Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* &gt; VectorOfValueStringVectors;
+
+    VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
+    for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
+        Vector&lt;ValueStringPair, 0, UnsafeVectorOverflow&gt;* tempSortingVector = *it;
+
+        Vector&lt;ValueStringPair&gt;::iterator vectorEnd = tempSortingVector-&gt;end();
+        for (Vector&lt;ValueStringPair&gt;::iterator vectorIt = tempSortingVector-&gt;begin(); vectorIt != vectorEnd; ++vectorIt) {
+            if (vectorIt-&gt;first)
+                heapRootVisitor.visit(&amp;vectorIt-&gt;first);
</ins><span class="cx">         }
</span><del>-        {
-            GCPHASE(VisitTempSortVectors);
-            MARK_LOG_ROOT(visitor, &quot;Temp Sort Vectors&quot;);
-            markTempSortVectors(heapRootVisitor);
-            visitor.donateAndDrain();
-        }
</del><ins>+    }
+    m_slotVisitor.donateAndDrain();
+}
</ins><span class="cx"> 
</span><del>-        {
-            GCPHASE(MarkingArgumentBuffers);
-            if (m_markListSet &amp;&amp; m_markListSet-&gt;size()) {
-                MARK_LOG_ROOT(visitor, &quot;Argument Buffers&quot;);
-                MarkedArgumentBuffer::markLists(heapRootVisitor, *m_markListSet);
-                visitor.donateAndDrain();
-            }
-        }
-        if (m_vm-&gt;exception()) {
-            GCPHASE(MarkingException);
-            MARK_LOG_ROOT(visitor, &quot;Exceptions&quot;);
-            heapRootVisitor.visit(m_vm-&gt;addressOfException());
-            visitor.donateAndDrain();
-        }
-    
-        {
-            GCPHASE(VisitStrongHandles);
-            MARK_LOG_ROOT(visitor, &quot;Strong Handles&quot;);
-            m_handleSet.visitStrongHandles(heapRootVisitor);
-            visitor.donateAndDrain();
-        }
-    
-        {
-            GCPHASE(HandleStack);
-            MARK_LOG_ROOT(visitor, &quot;Handle Stack&quot;);
-            m_handleStack.visit(heapRootVisitor);
-            visitor.donateAndDrain();
-        }
-    
-        {
-            GCPHASE(TraceCodeBlocksAndJITStubRoutines);
-            MARK_LOG_ROOT(visitor, &quot;Trace Code Blocks and JIT Stub Routines&quot;);
-            m_codeBlocks.traceMarked(visitor);
-            m_jitStubRoutines.traceMarkedStubRoutines(visitor);
-            visitor.donateAndDrain();
-        }
-    
</del><ins>+void Heap::visitArgumentBuffers(HeapRootVisitor&amp; visitor)
+{
+    GCPHASE(MarkingArgumentBuffers);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Argument Buffers&quot;);
+    if (!m_markListSet || !m_markListSet-&gt;size())
+        return;
+
+    MarkedArgumentBuffer::markLists(visitor, *m_markListSet);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitException(HeapRootVisitor&amp; visitor)
+{
+    GCPHASE(MarkingException);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Exceptions&quot;);
+    if (!m_vm-&gt;exception())
+        return;
+
+    visitor.visit(m_vm-&gt;addressOfException());
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitStrongHandles(HeapRootVisitor&amp; visitor)
+{
+    GCPHASE(VisitStrongHandles);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Strong Handles&quot;);
+    m_handleSet.visitStrongHandles(visitor);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::visitHandleStack(HeapRootVisitor&amp; visitor)
+{
+    GCPHASE(VisitHandleStack);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Handle Stack&quot;);
+    m_handleStack.visit(visitor);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::traceCodeBlocksAndJITStubRoutines()
+{
+    GCPHASE(TraceCodeBlocksAndJITStubRoutines);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Trace Code Blocks and JIT Stub Routines&quot;);
+    m_codeBlocks.traceMarked(m_slotVisitor);
+    m_jitStubRoutines.traceMarkedStubRoutines(m_slotVisitor);
+    m_slotVisitor.donateAndDrain();
+}
+
+void Heap::converge()
+{
</ins><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><del>-        {
-            GCPHASE(Convergence);
-            visitor.drainFromShared(SlotVisitor::MasterDrain);
-        }
</del><ins>+    GCPHASE(Convergence);
+    m_slotVisitor.drainFromShared(SlotVisitor::MasterDrain);
</ins><span class="cx"> #endif
</span><del>-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    // 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, &quot;Live Weak Handles&quot;);
-        while (true) {
-            m_objectSpace.visitWeakSets(heapRootVisitor);
-            harvestWeakReferences();
-            if (visitor.isEmpty())
-                break;
-            {
-                ParallelModeEnabler enabler(visitor);
-                visitor.donateAndDrain();
</del><ins>+void Heap::visitWeakHandles(HeapRootVisitor&amp; visitor)
+{
+    GCPHASE(VisitingLiveWeakHandles);
+    MARK_LOG_ROOT(m_slotVisitor, &quot;Live Weak Handles&quot;);
+    while (true) {
+        m_objectSpace.visitWeakSets(visitor);
+        harvestWeakReferences();
+        if (m_slotVisitor.isEmpty())
+            break;
+        {
+            ParallelModeEnabler enabler(m_slotVisitor);
+            m_slotVisitor.donateAndDrain();
</ins><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><del>-                visitor.drainFromShared(SlotVisitor::MasterDrain);
</del><ins>+            m_slotVisitor.drainFromShared(SlotVisitor::MasterDrain);
</ins><span class="cx"> #endif
</span><del>-            }
</del><span class="cx">         }
</span><span class="cx">     }
</span><ins>+}
</ins><span class="cx"> 
</span><ins>+void Heap::clearRememberedSet(Vector&lt;const JSCell*&gt;&amp; rememberedSet)
+{
</ins><span class="cx"> #if ENABLE(GGC)
</span><del>-    {
-        GCPHASE(ClearRememberedSet);
-        for (unsigned i = 0; i &lt; rememberedSet.size(); ++i) {
-            const JSCell* cell = rememberedSet[i];
-            MarkedBlock::blockFor(cell)-&gt;clearRemembered(cell);
-        }
</del><ins>+    GCPHASE(ClearRememberedSet);
+    for (unsigned i = 0; i &lt; rememberedSet.size(); ++i) {
+        const JSCell* cell = rememberedSet[i];
+        MarkedBlock::blockFor(cell)-&gt;clearRemembered(cell);
</ins><span class="cx">     }
</span><ins>+#else
+    UNUSED_PARAM(rememberedSet);
</ins><span class="cx"> #endif
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    GCCOUNTER(VisitedValueCount, visitor.visitCount());
</del><ins>+void Heap::updateObjectCounts()
+{
+    GCCOUNTER(VisitedValueCount, m_slotVisitor.visitCount());
</ins><span class="cx"> 
</span><del>-    m_sharedData.didFinishMarking();
</del><span class="cx"> #if ENABLE(OBJECT_MARK_LOGGING)
</span><del>-    size_t visitCount = visitor.visitCount();
</del><ins>+    size_t visitCount = m_slotVisitor.visitCount();
</ins><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><span class="cx">     visitCount += m_sharedData.childVisitCount();
</span><span class="cx"> #endif
</span><span class="lines">@@ -634,42 +692,28 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     if (m_operationInProgress == EdenCollection) {
</span><del>-        m_totalBytesVisited += visitor.bytesVisited();
-        m_totalBytesCopied += visitor.bytesCopied();
</del><ins>+        m_totalBytesVisited += m_slotVisitor.bytesVisited();
+        m_totalBytesCopied += m_slotVisitor.bytesCopied();
</ins><span class="cx">     } else {
</span><span class="cx">         ASSERT(m_operationInProgress == FullCollection);
</span><del>-        m_totalBytesVisited = visitor.bytesVisited();
-        m_totalBytesCopied = visitor.bytesCopied();
</del><ins>+        m_totalBytesVisited = m_slotVisitor.bytesVisited();
+        m_totalBytesCopied = m_slotVisitor.bytesCopied();
</ins><span class="cx">     }
</span><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><span class="cx">     m_totalBytesVisited += m_sharedData.childBytesVisited();
</span><span class="cx">     m_totalBytesCopied += m_sharedData.childBytesCopied();
</span><span class="cx"> #endif
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    visitor.reset();
</del><ins>+void Heap::resetVisitors()
+{
+    m_slotVisitor.reset();
</ins><span class="cx"> #if ENABLE(PARALLEL_GC)
</span><span class="cx">     m_sharedData.resetChildren();
</span><span class="cx"> #endif
</span><span class="cx">     m_sharedData.reset();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template &lt;HeapOperation collectionType&gt;
-void Heap::copyBackingStores()
-{
-    m_storageSpace.startedCopying&lt;collectionType&gt;();
-    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();
-}
-
</del><span class="cx"> size_t Heap::objectCount()
</span><span class="cx"> {
</span><span class="cx">     return m_objectSpace.objectCount();
</span><span class="lines">@@ -762,6 +806,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::deleteUnmarkedCompiledCode()
</span><span class="cx"> {
</span><ins>+    GCPHASE(DeleteCodeBlocks);
</ins><span class="cx">     ExecutableBase* next;
</span><span class="cx">     for (ExecutableBase* current = m_compiledCode.head(); current; current = next) {
</span><span class="cx">         next = current-&gt;next();
</span><span class="lines">@@ -825,14 +870,70 @@
</span><span class="cx">     ASSERT(m_isSafeToCollect);
</span><span class="cx">     JAVASCRIPTCORE_GC_BEGIN();
</span><span class="cx">     RELEASE_ASSERT(m_operationInProgress == NoOperation);
</span><del>-    
</del><ins>+
+    suspendCompilerThreads();
+    willStartCollection();
+
+    double gcStartTime = WTF::monotonicallyIncreasingTime();
+
+    deleteOldCode(gcStartTime);
+    flushOldStructureIDTables();
+    stopAllocation();
+    flushWriteBarrierBuffer();
+
+    markRoots();
+
+    JAVASCRIPTCORE_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, &quot; ms]\n&quot;);
+    }
+}
+
+bool Heap::collectIfNecessaryOrDefer()
+{
+    if (isDeferred())
+        return false;
+
+    if (!shouldCollect())
+        return false;
+
+    collect();
+    return true;
+}
+
+void Heap::suspendCompilerThreads()
+{
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><ins>+    GCPHASE(SuspendCompilerThreads);
</ins><span class="cx">     for (unsigned i = DFG::numberOfWorklists(); i--;) {
</span><span class="cx">         if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
</span><span class="cx">             worklist-&gt;suspendAllThreads();
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><ins>+}
</ins><span class="cx"> 
</span><ins>+void Heap::willStartCollection()
+{
+    GCPHASE(StartingCollection);
</ins><span class="cx">     if (shouldDoFullCollection()) {
</span><span class="cx">         m_operationInProgress = FullCollection;
</span><span class="cx">         m_slotVisitor.clearMarkStack();
</span><span class="lines">@@ -849,84 +950,93 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_activityCallback)
</span><span class="cx">         m_activityCallback-&gt;willCollect();
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    double lastGCStartTime = WTF::monotonicallyIncreasingTime();
-    if (lastGCStartTime - m_lastCodeDiscardTime &gt; minute) {
</del><ins>+void Heap::deleteOldCode(double gcStartTime)
+{
+    GCPHASE(DeleteOldCode);
+    if (gcStartTime - m_lastCodeDiscardTime &gt; minute) {
</ins><span class="cx">         deleteAllCompiledCode();
</span><span class="cx">         m_lastCodeDiscardTime = WTF::monotonicallyIncreasingTime();
</span><span class="cx">     }
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(StopAllocation);
-        m_structureIDTable.flushOldTables();
-        m_objectSpace.stopAllocating();
-        if (m_operationInProgress == FullCollection)
-            m_storageSpace.didStartFullCollection();
-    }
</del><ins>+void Heap::flushOldStructureIDTables()
+{
+    GCPHASE(FlushOldStructureIDTables);
+    m_structureIDTable.flushOldTables();
+}
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(FlushWriteBarrierBuffer);
-        if (m_operationInProgress == EdenCollection)
-            m_writeBarrierBuffer.flush(*this);
-        else
-            m_writeBarrierBuffer.reset();
</del><ins>+void Heap::flushWriteBarrierBuffer()
+{
+    GCPHASE(FlushWriteBarrierBuffer);
+    if (m_operationInProgress == EdenCollection) {
+        m_writeBarrierBuffer.flush(*this);
+        return;
</ins><span class="cx">     }
</span><ins>+    m_writeBarrierBuffer.reset();
+}
</ins><span class="cx"> 
</span><del>-    markRoots();
-    
-    {
-        GCPHASE(ReapingWeakHandles);
-        m_objectSpace.reapWeakSets();
-    }
</del><ins>+void Heap::stopAllocation()
+{
+    GCPHASE(StopAllocation);
+    m_objectSpace.stopAllocating();
+    if (m_operationInProgress == FullCollection)
+        m_storageSpace.didStartFullCollection();
+}
</ins><span class="cx"> 
</span><del>-    JAVASCRIPTCORE_GC_MARKED();
-    
-    {
-        GCPHASE(SweepingArrayBuffers);
-        m_arrayBuffers.sweep();
-    }
</del><ins>+void Heap::reapWeakHandles()
+{
+    GCPHASE(ReapingWeakHandles);
+    m_objectSpace.reapWeakSets();
+}
</ins><span class="cx"> 
</span><del>-    if (m_operationInProgress == FullCollection) {
-        m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
-        MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
-        m_objectSpace.forEachBlock(functor);
-    }
</del><ins>+void Heap::sweepArrayBuffers()
+{
+    GCPHASE(SweepingArrayBuffers);
+    m_arrayBuffers.sweep();
+}
</ins><span class="cx"> 
</span><del>-    if (m_operationInProgress == FullCollection)
-        copyBackingStores&lt;FullCollection&gt;();
-    else
-        copyBackingStores&lt;EdenCollection&gt;();
</del><ins>+void Heap::snapshotMarkedSpace()
+{
+    GCPHASE(SnapshotMarkedSpace);
+    if (m_operationInProgress != FullCollection)
+        return;
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(FinalizeUnconditionalFinalizers);
-        finalizeUnconditionalFinalizers();
-    }
</del><ins>+    m_blockSnapshot.resize(m_objectSpace.blocks().set().size());
+    MarkedBlockSnapshotFunctor functor(m_blockSnapshot);
+    m_objectSpace.forEachBlock(functor);
+}
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(DeleteCodeBlocks);
-        deleteUnmarkedCompiledCode();
-    }
</del><ins>+void Heap::deleteSourceProviderCaches()
+{
+    GCPHASE(DeleteSourceProviderCaches);
+    m_vm-&gt;clearSourceProviderCaches();
+}
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(DeleteSourceProviderCaches);
-        m_vm-&gt;clearSourceProviderCaches();
-    }
</del><ins>+void Heap::notifyIncrementalSweeper()
+{
+    GCPHASE(NotifyIncrementalSweeper);
+    if (m_operationInProgress != FullCollection)
+        return;
+    m_sweeper-&gt;startSweeping(m_blockSnapshot);
+}
</ins><span class="cx"> 
</span><del>-    if (m_operationInProgress == FullCollection)
-        m_sweeper-&gt;startSweeping(m_blockSnapshot);
</del><ins>+void Heap::rememberCurrentlyExecutingCodeBlocks()
+{
+    GCPHASE(RememberCurrentlyExecutingCodeBlocks);
+    m_codeBlocks.rememberCurrentlyExecutingCodeBlocks(this);
+}
</ins><span class="cx"> 
</span><del>-    {
-        GCPHASE(AddCurrentlyExecutingCodeBlocksToRememberedSet);
-        m_codeBlocks.rememberCurrentlyExecutingCodeBlocks(this);
-    }
</del><ins>+void Heap::resetAllocators()
+{
+    GCPHASE(ResetAllocators);
+    m_objectSpace.resetAllocators();
+}
</ins><span class="cx"> 
</span><del>-    m_bytesAbandonedThisCycle = 0;
-
-    {
-        GCPHASE(ResetAllocators);
-        m_objectSpace.resetAllocators();
-    }
-    
</del><ins>+void Heap::updateAllocationLimits()
+{
+    GCPHASE(UpdateAllocationLimits);
</ins><span class="cx">     size_t currentHeapSize = sizeAfterCollect();
</span><span class="cx">     if (Options::gcMaxHeapSize() &amp;&amp; currentHeapSize &gt; Options::gcMaxHeapSize())
</span><span class="cx">         HeapStatistics::exitWithFailure();
</span><span class="lines">@@ -949,13 +1059,21 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_sizeAfterLastCollect = currentHeapSize;
</span><del>-
</del><span class="cx">     m_bytesAllocatedThisCycle = 0;
</span><del>-    double lastGCEndTime = WTF::monotonicallyIncreasingTime();
-    m_lastGCLength = lastGCEndTime - lastGCStartTime;
</del><ins>+    m_bytesAbandonedThisCycle = 0;
</ins><span class="cx"> 
</span><ins>+    if (Options::logGC())
+        dataLog(currentHeapSize / 1024, &quot; kb, &quot;);
+}
+
+void Heap::didFinishCollection(double gcStartTime)
+{
+    GCPHASE(FinishingCollection);
+    double gcEndTime = WTF::monotonicallyIncreasingTime();
+    m_lastGCLength = gcEndTime - gcStartTime;
+
</ins><span class="cx">     if (Options::recordGCPauseTimes())
</span><del>-        HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime);
</del><ins>+        HeapStatistics::recordGCPauseTime(gcStartTime, gcEndTime);
</ins><span class="cx">     RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
</span><span class="cx"> 
</span><span class="cx">     m_operationInProgress = NoOperation;
</span><span class="lines">@@ -969,32 +1087,19 @@
</span><span class="cx"> 
</span><span class="cx">     if (Options::showObjectStatistics())
</span><span class="cx">         HeapStatistics::showObjectStatistics(this);
</span><del>-    
</del><ins>+}
+
+void Heap::resumeCompilerThreads()
+{
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><ins>+    GCPHASE(ResumeCompilerThreads);
</ins><span class="cx">     for (unsigned i = DFG::numberOfWorklists(); i--;) {
</span><span class="cx">         if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
</span><span class="cx">             worklist-&gt;resumeAllThreads();
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><del>-
-    if (Options::logGC()) {
-        double after = currentTimeMS();
-        dataLog(after - before, &quot; ms, &quot;, currentHeapSize / 1024, &quot; kb]\n&quot;);
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::collectIfNecessaryOrDefer()
-{
-    if (isDeferred())
-        return false;
-
-    if (!shouldCollect())
-        return false;
-
-    collect();
-    return true;
-}
-
</del><span class="cx"> void Heap::markDeadObjects()
</span><span class="cx"> {
</span><span class="cx">     HeapIterationScope iterationScope(*this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (164861 => 164862)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2014-02-28 16:35:27 UTC (rev 164861)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2014-02-28 16:56:17 UTC (rev 164862)
</span><span class="lines">@@ -248,14 +248,48 @@
</span><span class="cx">         JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
</span><span class="cx">         JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);
</span><span class="cx"> 
</span><ins>+        void suspendCompilerThreads();
+        void willStartCollection();
+        void deleteOldCode(double gcStartTime);
+        void flushOldStructureIDTables();
+        void flushWriteBarrierBuffer();
+        void stopAllocation();
+
</ins><span class="cx">         void markRoots();
</span><del>-        void markProtectedObjects(HeapRootVisitor&amp;);
-        void markTempSortVectors(HeapRootVisitor&amp;);
-        template &lt;HeapOperation collectionType&gt;
</del><ins>+        void gatherStackRoots(ConservativeRoots&amp;, void** dummy);
+        void gatherJSStackRoots(ConservativeRoots&amp;);
+        void gatherScratchBufferRoots(ConservativeRoots&amp;);
+        void clearLivenessData();
+        void visitSmallStrings();
+        void visitConservativeRoots(ConservativeRoots&amp;);
+        void visitCompilerWorklists();
+        void visitProtectedObjects(HeapRootVisitor&amp;);
+        void visitTempSortVectors(HeapRootVisitor&amp;);
+        void visitArgumentBuffers(HeapRootVisitor&amp;);
+        void visitException(HeapRootVisitor&amp;);
+        void visitStrongHandles(HeapRootVisitor&amp;);
+        void visitHandleStack(HeapRootVisitor&amp;);
+        void traceCodeBlocksAndJITStubRoutines();
+        void converge();
+        void visitWeakHandles(HeapRootVisitor&amp;);
+        void clearRememberedSet(Vector&lt;const JSCell*&gt;&amp;);
+        void updateObjectCounts();
+        void resetVisitors();
+
+        void reapWeakHandles();
+        void sweepArrayBuffers();
+        void snapshotMarkedSpace();
+        void deleteSourceProviderCaches();
+        void notifyIncrementalSweeper();
+        void rememberCurrentlyExecutingCodeBlocks();
+        void resetAllocators();
</ins><span class="cx">         void copyBackingStores();
</span><span class="cx">         void harvestWeakReferences();
</span><span class="cx">         void finalizeUnconditionalFinalizers();
</span><span class="cx">         void deleteUnmarkedCompiledCode();
</span><ins>+        void updateAllocationLimits();
+        void didFinishCollection(double gcStartTime);
+        void resumeCompilerThreads();
</ins><span class="cx">         void zombifyDeadObjects();
</span><span class="cx">         void markDeadObjects();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>