Bug 720292 - add more cycle collector edge names. r=smaug
authorAndrew McCreight <amccreight@mozilla.com>
Mon, 23 Jan 2012 15:25:53 -0800
changeset 85143 56ee4d79fd79c5c956a1c98cc9474fc817e9fc68
parent 85142 3098655dc8a5399b59ba83d28613d3d7f05886ae
child 85144 66dc5e17869162b8a3276b7692d7b050232131d9
push id5194
push useramccreight@mozilla.com
push dateMon, 23 Jan 2012 23:26:20 +0000
treeherdermozilla-inbound@56ee4d79fd79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs720292
milestone12.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 720292 - add more cycle collector edge names. r=smaug
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xul/content/src/nsXULElement.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/nsXPConnect.cpp
xpcom/ds/nsVariant.cpp
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -304,16 +304,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NA
                                             tmp->mContent);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextBinding)
   delete tmp->mInsertionPointTable;
   tmp->mInsertionPointTable = nsnull;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXBLBinding)
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+                                     "mPrototypeBinding->XBLDocumentInfo()");
   cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObjectOwner*>(
                       tmp->mPrototypeBinding->XBLDocumentInfo()));
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNextBinding, nsXBLBinding)
   if (tmp->mInsertionPointTable)
     tmp->mInsertionPointTable->EnumerateRead(TraverseKey, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXBLBinding, AddRef)
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -471,16 +471,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
       nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
   if (tmp->mBindingTable) {
     tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
   }
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
   cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
     ProtoTracer closure = { aCallback, aClosure };
     tmp->mBindingTable->Enumerate(TraceProtos, &closure);
   }
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -380,26 +380,30 @@ TraverseInsertionPoint(nsHashKey* aKey, 
   return kHashEnumerateNext;
 }
 
 static bool
 TraverseBinding(nsHashKey *aKey, void *aData, void* aClosure)
 {
   nsCycleCollectionTraversalCallback *cb = 
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME((*cb), "proto mInterfaceTable data");
   cb->NoteXPCOMChild(static_cast<nsISupports*>(aData));
   return kHashEnumerateNext;
 }
 
 void
 nsXBLPrototypeBinding::Traverse(nsCycleCollectionTraversalCallback &cb) const
 {
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mBinding");
   cb.NoteXPCOMChild(mBinding);
-  if (mResources)
+  if (mResources) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "proto mResources mLoader");
     cb.NoteXPCOMChild(mResources->mLoader);
+  }
   if (mInsertionPointTable)
     mInsertionPointTable->Enumerate(TraverseInsertionPoint, &cb);
   if (mInterfaceTable)
     mInterfaceTable->Enumerate(TraverseBinding, &cb);
 }
 
 void
 nsXBLPrototypeBinding::UnlinkJSObjects()
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -700,16 +700,17 @@ nsXULElement::PerformAccesskey(bool aKey
 //----------------------------------------------------------------------
 // nsIScriptEventHandlerOwner interface
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptEventHandlerOwnerTearoff)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptEventHandlerOwnerTearoff)
   tmp->mElement = nsnull;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptEventHandlerOwnerTearoff)
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mElement");
   cb.NoteXPCOMChild(static_cast<nsIContent*>(tmp->mElement));
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptEventHandlerOwnerTearoff)
   NS_INTERFACE_MAP_ENTRY(nsIScriptEventHandlerOwner)
 NS_INTERFACE_MAP_END_AGGREGATED(mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptEventHandlerOwnerTearoff)
@@ -2540,22 +2541,26 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NA
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         static_cast<nsXULPrototypeScript*>(tmp)->UnlinkJSObjects();
     }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         nsXULPrototypeElement *elem =
             static_cast<nsXULPrototypeElement*>(tmp);
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mNodeInfo");
         cb.NoteXPCOMChild(elem->mNodeInfo);
         PRUint32 i;
         for (i = 0; i < elem->mNumAttributes; ++i) {
             const nsAttrName& name = elem->mAttributes[i].mName;
-            if (!name.IsAtom())
+            if (!name.IsAtom()) {
+                NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
+                    "mAttributes[i].mName.NodeInfo()");
                 cb.NoteXPCOMChild(name.NodeInfo());
+            }
         }
         for (i = 0; i < elem->mChildren.Length(); ++i) {
             NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(elem->mChildren[i].get(),
                                                          nsXULPrototypeNode,
                                                          "mChildren[i]")
         }
     }
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -113,19 +113,21 @@ void
 XPCTraceableVariant::PrintTraceName(JSTracer* trc, char *buf, size_t bufsize)
 {
     JS_snprintf(buf, bufsize, "XPCVariant[0x%p].mJSVal", trc->debugPrintArg);
 }
 #endif
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant)
     jsval val = tmp->GetJSValPreserveColor();
-    if (JSVAL_IS_OBJECT(val))
+    if (JSVAL_IS_OBJECT(val)) {
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSVal");
         cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT,
                            JSVAL_TO_OBJECT(val));
+    }
 
     nsVariant::Traverse(tmp->mData, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant)
     jsval val = tmp->GetJSValPreserveColor();
 
     // We're sharing val's buffer, clear the pointer to it so Cleanup() won't
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -70,31 +70,37 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrapp
             JS_snprintf(name, sizeof(name), "nsXPCWrappedJS");
         cb.DescribeRefCountedNode(refcnt, sizeof(nsXPCWrappedJS), name);
     } else {
         NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsXPCWrappedJS, refcnt)
     }
 
     // nsXPCWrappedJS keeps its own refcount artificially at or above 1, see the
     // comment above nsXPCWrappedJS::AddRef.
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "self");
     cb.NoteXPCOMChild(s);
 
-    if (refcnt > 1)
+    if (refcnt > 1) {
         // nsXPCWrappedJS roots its mJSObj when its refcount is > 1, see
         // the comment above nsXPCWrappedJS::AddRef.
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSObj");
         cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT,
                            tmp->GetJSObjectPreserveColor());
+    }
 
     nsXPCWrappedJS* root = tmp->GetRootWrapper();
-    if (root == tmp)
+    if (root == tmp) {
         // The root wrapper keeps the aggregated native object alive.
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "aggregated native");
         cb.NoteXPCOMChild(tmp->GetAggregatedNativeObject());
-    else
+    } else {
         // Non-root wrappers keep their root alive.
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "root");
         cb.NoteXPCOMChild(static_cast<nsIXPConnectWrappedJS*>(root));
+    }
 
     return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPCWrappedJS)
     tmp->Unlink();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1018,18 +1018,18 @@ public:
         JSContext *cx = static_cast<JSContext*>(n);
 
         // Add outstandingRequests to the count, if there are outstanding
         // requests the context needs to be kept alive and adding unknown
         // edges will ensure that any cycles this context is in won't be
         // collected.
         unsigned refCount = nsXPConnect::GetXPConnect()->GetOutstandingRequests(cx) + 1;
         cb.DescribeRefCountedNode(refCount, js::SizeOfJSContext(), "JSContext");
-        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[global object]");
         if (JSObject *global = JS_GetGlobalObject(cx)) {
+            NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[global object]");
             cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, global);
         }
 
         return NS_OK;
     }
 };
 
 static JSContextParticipant JSContext_cycleCollectorGlobal;
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -1663,26 +1663,29 @@ nsVariant::Cleanup(nsDiscriminatedUnion*
 /* static */ void
 nsVariant::Traverse(const nsDiscriminatedUnion& data,
                     nsCycleCollectionTraversalCallback &cb)
 {
     switch(data.mType)
     {
         case nsIDataType::VTYPE_INTERFACE:
         case nsIDataType::VTYPE_INTERFACE_IS:
+            NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData");
             cb.NoteXPCOMChild(data.u.iface.mInterfaceValue);
             break;
         case nsIDataType::VTYPE_ARRAY:
             switch(data.u.array.mArrayType) {
                 case nsIDataType::VTYPE_INTERFACE:
                 case nsIDataType::VTYPE_INTERFACE_IS:
                 {
                     nsISupports** p = (nsISupports**) data.u.array.mArrayValue;
-                    for(PRUint32 i = data.u.array.mArrayCount; i > 0; p++, i--)
+                    for(PRUint32 i = data.u.array.mArrayCount; i > 0; p++, i--) {
+                        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mData[i]");
                         cb.NoteXPCOMChild(*p);
+                    }
                 }
                 default:
                     break;
             }
         default:
             break;
     }
 }