Bug 937751, part 6 - Allocate the current MarkRoots node on the heap rather than the stack. r=smaug
authorAndrew McCreight <continuation@gmail.com>
Tue, 03 Dec 2013 10:47:47 -0800
changeset 158640 2c9c18bf7d364b1ed793f51b8025f32d7046f23e
parent 158639 d2a69e306fb5f8a0e7d24fa7e5cdee34a5add254
child 158641 988a78637574ac3517a90b9a15d1c50534099f15
push id25752
push usercbook@mozilla.com
push dateWed, 04 Dec 2013 08:35:03 +0000
treeherdermozilla-central@8187818246ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs937751
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 937751, part 6 - Allocate the current MarkRoots node on the heap rather than the stack. r=smaug To make nsCycleCollector::MarkRoots incremental, we have to store all of its state on the heap, so we can resume it. The only remaining state to convert is the NodePool enumerator.
xpcom/base/nsCycleCollector.cpp
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -1015,16 +1015,17 @@ class nsCycleCollector : public MemoryMu
     CycleCollectorResults mResults;
     TimeStamp mCollectionStart;
 
     CycleCollectedJSRuntime *mJSRuntime;
 
     ccPhase mIncrementalPhase;
     GCGraph mGraph;
     nsAutoPtr<GCGraphBuilder> mBuilder;
+    nsAutoPtr<NodePool::Enumerator> mCurrNode;
     nsCOMPtr<nsICycleCollectorListener> mListener;
 
     nsIThread* mThread;
 
     nsCycleCollectorParams mParams;
 
     uint32_t mWhiteNodeCount;
 
@@ -2212,37 +2213,37 @@ nsCycleCollector::ForgetSkippable(bool a
 MOZ_NEVER_INLINE void
 nsCycleCollector::MarkRoots()
 {
     TimeLog timeLog;
     AutoRestore<bool> ar(mScanInProgress);
     MOZ_ASSERT(!mScanInProgress);
     mScanInProgress = true;
     MOZ_ASSERT(mIncrementalPhase == GraphBuildingPhase);
-
-    // read the PtrInfo out of the graph that we are building
-    NodePool::Enumerator queue(mGraph.mNodes);
-    while (!queue.IsDone()) {
-        PtrInfo *pi = queue.GetNext();
+    MOZ_ASSERT(mCurrNode);
+
+    while (!mCurrNode->IsDone()) {
+        PtrInfo *pi = mCurrNode->GetNext();
         CC_AbortIfNull(pi);
         mBuilder->Traverse(pi);
-        if (queue.AtBlockEnd()) {
+        if (mCurrNode->AtBlockEnd()) {
             mBuilder->SetLastChild();
         }
     }
     if (mGraph.mRootCount > 0) {
         mBuilder->SetLastChild();
     }
 
     if (mBuilder->RanOutOfMemory()) {
         MOZ_ASSERT(false, "Ran out of memory while building cycle collector graph");
         CC_TELEMETRY(_OOM, true);
     }
 
     mBuilder = nullptr;
+    mCurrNode = nullptr;
     mIncrementalPhase = ScanAndCollectWhitePhase;
     timeLog.Checkpoint("MarkRoots()");
 }
 
 
 ////////////////////////////////////////////////////////////////////////
 // Bacon & Rajan's |ScanRoots| routine.
 ////////////////////////////////////////////////////////////////////////
@@ -2897,16 +2898,17 @@ nsCycleCollector::BeginCollection(ccType
     MOZ_ASSERT(!mScanInProgress);
     mScanInProgress = true;
     mPurpleBuf.SelectPointers(*mBuilder);
     timeLog.Checkpoint("SelectPointers()");
 
     // We've finished adding roots, and everything in the graph is a root.
     mGraph.mRootCount = mGraph.MapCount();
 
+    mCurrNode = new NodePool::Enumerator(mGraph.mNodes);
     mIncrementalPhase = GraphBuildingPhase;
 }
 
 uint32_t
 nsCycleCollector::SuspectedCount()
 {
     CheckThreadSafety();
     return mPurpleBuf.Count();