Bug 658386 - part 2: eliminate redundant stores of PtrInfo child pointers. r=peterv
authorAndrew McCreight <amccreight@mozilla.com>
Thu, 09 Jun 2011 14:55:29 -0700
changeset 70896 3f40708323d91f38ff529008d05ad31206e01bc1
parent 70895 6c24a513319a1343ffa6782c1542160b6658ddc9
child 70897 f47664f19b08a452b40c735e100bf97bd12caa53
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerspeterv
bugs658386
milestone7.0a1
Bug 658386 - part 2: eliminate redundant stores of PtrInfo child pointers. r=peterv
xpcom/base/nsCycleCollector.cpp
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -649,16 +649,21 @@ public:
         {
         }
 
         PRBool IsDone() const
         {
             return mNext == mLast;
         }
 
+        PRBool AtBlockEnd() const
+        {
+            return mNext == mBlockEnd;
+        }
+
         PtrInfo* GetNext()
         {
             NS_ASSERTION(!IsDone(), "calling GetNext when done");
             if (mNext == mBlockEnd) {
                 Block *nextBlock = mCurBlock ? mCurBlock->mNext : mFirstBlock;
                 mNext = nextBlock->mEntries;
                 mBlockEnd = mNext + BlockSize;
                 mCurBlock = nextBlock;
@@ -1447,16 +1452,17 @@ public:
     PtrInfo* AddNode(void *s, nsCycleCollectionParticipant *aParticipant);
     PtrInfo* AddNode(void *s, nsCycleCollectionParticipant *aParticipant,
                      PRUint32 aLangID)
     {
         return AddNode(s, aParticipant);
     }
 #endif
     void Traverse(PtrInfo* aPtrInfo);
+    void SetLastChild();
 
     // nsCycleCollectionTraversalCallback methods.
     NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root);
 
 private:
     NS_IMETHOD_(void) DescribeNode(CCNodeType type, nsrefcnt refCount,
                                    size_t objSz, const char *objName);
     NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void *child,
@@ -1537,24 +1543,27 @@ GCGraphBuilder::Traverse(PtrInfo* aPtrIn
 
 #ifdef DEBUG_CC
     if (!mCurrPi->mParticipant) {
         Fault("unknown pointer during walk", aPtrInfo);
         return;
     }
 #endif
 
-    // this is redundant except at the start of a NodePool block
     mCurrPi->SetFirstChild(mEdgeBuilder.Mark());
 
     nsresult rv = aPtrInfo->mParticipant->Traverse(aPtrInfo->mPointer, *this);
     if (NS_FAILED(rv)) {
         Fault("script pointer traversal failed", aPtrInfo);
     }
-
+}
+
+void
+GCGraphBuilder::SetLastChild()
+{
     mCurrPi->SetLastChild(mEdgeBuilder.Mark());
 }
 
 NS_IMETHODIMP_(void)
 GCGraphBuilder::NoteXPCOMRoot(nsISupports *root)
 {
     root = canonicalize(root);
     NS_ASSERTION(root,
@@ -1790,17 +1799,21 @@ nsCycleCollector::MarkRoots(GCGraphBuild
 {
     mGraph.mRootCount = builder.Count();
 
     // read the PtrInfo out of the graph that we are building
     NodePool::Enumerator queue(mGraph.mNodes);
     while (!queue.IsDone()) {
         PtrInfo *pi = queue.GetNext();
         builder.Traverse(pi);
+        if (queue.AtBlockEnd())
+            builder.SetLastChild();
     }
+    if (mGraph.mRootCount > 0)
+        builder.SetLastChild();
 }
 
 
 ////////////////////////////////////////////////////////////////////////
 // Bacon & Rajan's |ScanRoots| routine.
 ////////////////////////////////////////////////////////////////////////