Bug 664452, unlink XUL some more, r=peterv
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 01 Jul 2011 17:02:04 +0300
changeset 72141 6cf983334e7add24d79ec85f1a5c2386e69d4d23
parent 72140 52ba94702d12e255804ba44702c02052ec7cdcc1
child 72142 c97034c07fe6e07f92b4bdf5fabdcbb380f15ca6
push id20664
push useropettay@mozilla.com
push dateFri, 01 Jul 2011 21:39:18 +0000
treeherdermozilla-central@c97034c07fe6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs664452
milestone7.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 664452, unlink XUL some more, r=peterv
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/templates/src/nsTemplateMatch.h
content/xul/templates/src/nsXULTemplateBuilder.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
content/xul/templates/src/nsXULTreeBuilder.cpp
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -386,16 +386,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
         tmp->mOverlayLoadObservers.EnumerateRead(TraverseObservers, &cb);
     if (tmp->mPendingOverlayLoadNotifications.IsInitialized())
         tmp->mPendingOverlayLoadNotifications.EnumerateRead(TraverseObservers, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULDocument, nsXMLDocument)
     delete tmp->mTemplateBuilderTable;
     tmp->mTemplateBuilderTable = nsnull;
+
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCommandDispatcher)
     //XXX We should probably unlink all the objects we traverse.
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(nsXULDocument, nsXMLDocument)
 NS_IMPL_RELEASE_INHERITED(nsXULDocument, nsXMLDocument)
 
 
 DOMCI_NODE_DATA(XULDocument, nsXULDocument)
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -185,23 +185,30 @@ nsXULPrototypeDocument::~nsXULPrototypeD
 
     if (--gRefCnt == 0) {
         NS_IF_RELEASE(gSystemPrincipal);
         NS_IF_RELEASE(gSystemGlobal);
     }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPrototypeDocument)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsXULPrototypeDocument)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeDocument)
+    tmp->mPrototypeWaiters.Clear();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeDocument)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mRoot,
                                                     nsXULPrototypeElement)
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
     cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
                                                     nsNodeInfoManager)
+    for (PRUint32 i = 0; i < tmp->mPrototypeWaiters.Length(); ++i) {
+        NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypeWaiters[i]");
+        cb.NoteXPCOMChild(static_cast<nsINode*>(tmp->mPrototypeWaiters[i].get()));
+    }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPrototypeDocument)
     NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObjectOwner)
     NS_INTERFACE_MAP_ENTRY(nsISerializable)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObjectOwner)
 NS_INTERFACE_MAP_END
 
--- a/content/xul/templates/src/nsTemplateMatch.h
+++ b/content/xul/templates/src/nsTemplateMatch.h
@@ -76,19 +76,25 @@ private:
 public:
     nsTemplateMatch(PRUint16 aQuerySetPriority,
                     nsIXULTemplateResult* aResult,
                     nsIContent* aContainer)
         : mRuleIndex(-1),
           mQuerySetPriority(aQuerySetPriority),
           mContainer(aContainer),
           mResult(aResult),
-          mNext(nsnull) {}
+          mNext(nsnull)
+    {
+      MOZ_COUNT_CTOR(nsTemplateMatch);
+    }
 
-    ~nsTemplateMatch() {}
+    ~nsTemplateMatch()
+    {
+      MOZ_COUNT_DTOR(nsTemplateMatch);
+    }
 
     static nsTemplateMatch*
     Create(nsFixedSizeAllocator& aPool,
            PRUint16 aQuerySetPriority,
            nsIXULTemplateResult* aResult,
            nsIContent* aContainer) {
         void* place = aPool.Alloc(sizeof(nsTemplateMatch));
         return place ? ::new (place) nsTemplateMatch(aQuerySetPriority,
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -270,16 +270,21 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCompDB)
     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot)
     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRootResult)
     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mListeners)
     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQueryProcessor)
     if (tmp->mMatchMap.IsInitialized()) {
       tmp->mMatchMap.Enumerate(DestroyMatchList, &(tmp->mPool));
     }
+    for (PRUint32 i = 0; i < tmp->mQuerySets.Length(); ++i) {
+        nsTemplateQuerySet* qs = tmp->mQuerySets[i];
+        delete qs;
+    }
+    tmp->mQuerySets.Clear();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateBuilder)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDataSource)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDB)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCompDB)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRootResult)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mListeners)
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -81,17 +81,19 @@ static NS_DEFINE_CID(kRDFServiceCID,    
 
 nsrefcnt                  nsXULTemplateQueryProcessorRDF::gRefCnt = 0;
 nsIRDFService*            nsXULTemplateQueryProcessorRDF::gRDFService;
 nsIRDFContainerUtils*     nsXULTemplateQueryProcessorRDF::gRDFContainerUtils;
 nsIRDFResource*           nsXULTemplateQueryProcessorRDF::kNC_BookmarkSeparator;
 nsIRDFResource*           nsXULTemplateQueryProcessorRDF::kRDF_type;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorRDF)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsXULTemplateQueryProcessorRDF)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorRDF)
+    tmp->Done();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 static PLDHashOperator
 BindingDependenciesTraverser(nsISupports* key,
                              nsCOMArray<nsXULTemplateResultRDF>* array,
                              void* userArg)
 {
     nsCycleCollectionTraversalCallback *cb = 
         static_cast<nsCycleCollectionTraversalCallback*>(userArg);
@@ -1051,17 +1053,17 @@ nsXULTemplateQueryProcessorRDF::Synchron
                                                nsIRDFNode* aOldTarget,
                                                nsIRDFNode* aNewTarget)
 {
     // Update each match that contains <aSource, aProperty, aOldTarget>.
 
     // Get all the matches whose assignments are currently supported
     // by aSource and aProperty: we'll need to recompute them.
     nsCOMArray<nsXULTemplateResultRDF>* results;
-    if (!mBindingDependencies.Get(aSource, &results))
+    if (!mBindingDependencies.Get(aSource, &results) || !mBuilder)
         return NS_OK;
 
     PRUint32 length = results->Count();
 
     for (PRUint32 r = 0; r < length; r++) {
         nsXULTemplateResultRDF* result = (*results)[r];
         if (result) {
             // synchronize the result's bindings and then update the builder
@@ -1120,16 +1122,17 @@ nsXULTemplateQueryProcessorRDF::Log(cons
 }
 #endif
 
 nsresult
 nsXULTemplateQueryProcessorRDF::CheckContainer(nsIRDFResource* aResource,
                                                PRBool* aIsContainer)
 {
     NS_ENSURE_ARG_POINTER(aIsContainer);
+    NS_ENSURE_STATE(mDB);
 
     // We have to look at all of the arcs extending out of the
     // resource: if any of them are that "containment" property, then
     // we know we'll have children.
     PRBool isContainer = PR_FALSE;
 
     for (nsResourceSet::ConstIterator property = mContainmentProperties.First();
          property != mContainmentProperties.Last();
@@ -1154,16 +1157,17 @@ nsXULTemplateQueryProcessorRDF::CheckCon
 
     return NS_OK;
 }
 
 nsresult
 nsXULTemplateQueryProcessorRDF::CheckEmpty(nsIRDFResource* aResource,
                                            PRBool* aIsEmpty)
 {
+    NS_ENSURE_STATE(mDB);
     *aIsEmpty = PR_TRUE;
 
     for (nsResourceSet::ConstIterator property = mContainmentProperties.First();
          property != mContainmentProperties.Last();
          property++) {
 
         nsCOMPtr<nsIRDFNode> dummy;
         mDB->GetTarget(aResource, *property, PR_TRUE, getter_AddRefs(dummy));
@@ -1181,16 +1185,17 @@ nsXULTemplateQueryProcessorRDF::CheckEmp
 
     return NS_OK;
 }
 
 nsresult
 nsXULTemplateQueryProcessorRDF::CheckIsSeparator(nsIRDFResource* aResource,
                                                  PRBool* aIsSeparator)
 {
+    NS_ENSURE_STATE(mDB);
     return mDB->HasAssertion(aResource, kRDF_type, kNC_BookmarkSeparator,
                              PR_TRUE, aIsSeparator);
 }
 
 //----------------------------------------------------------------------
 
 nsresult
 nsXULTemplateQueryProcessorRDF::ComputeContainmentProperties(nsIDOMNode* aRootNode)
@@ -1898,17 +1903,17 @@ nsXULTemplateQueryProcessorRDF::RetractE
 
 PRInt32
 nsXULTemplateQueryProcessorRDF::GetContainerIndexOf(nsIXULTemplateResult* aResult)
 {
     // get the reference variable and look up the container in the result
     nsCOMPtr<nsISupports> ref;
     nsresult rv = aResult->GetBindingObjectFor(mRefVariable,
                                                getter_AddRefs(ref));
-    if (NS_FAILED(rv))
+    if (NS_FAILED(rv) || !mDB)
         return -1;
 
     nsCOMPtr<nsIRDFResource> container = do_QueryInterface(ref);
     if (container) {
         // if the container is an RDF Seq, return the index of the result
         // in the container.
         PRBool isSequence = PR_FALSE;
         gRDFContainerUtils->IsSeq(mDB, container, &isSequence);
@@ -1935,17 +1940,17 @@ nsXULTemplateQueryProcessorRDF::GetSortV
                                              nsISupports** aResultNode)
 {
     nsCOMPtr<nsIRDFResource> source;
     nsresult rv = aResult->GetResource(getter_AddRefs(source));
     if (NS_FAILED(rv))
         return rv;
     
     nsCOMPtr<nsIRDFNode> value;
-    if (source) {
+    if (source && mDB) {
         // first check predicate?sort=true so that datasources may use a
         // custom value for sorting
         rv = mDB->GetTarget(source, aSortPredicate, PR_TRUE,
                             getter_AddRefs(value));
         if (NS_FAILED(rv))
             return rv;
 
         if (!value) {
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -76,16 +76,17 @@
  */
 class nsXULTreeBuilder : public nsXULTemplateBuilder,
                          public nsIXULTreeBuilder,
                          public nsINativeTreeView
 {
 public:
     // nsISupports
     NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
 
     // nsIXULTreeBuilder
     NS_DECL_NSIXULTREEBUILDER
 
     // nsITreeView
     NS_DECL_NSITREEVIEW
     // nsINativeTreeView: Untrusted code can use us
     NS_IMETHOD EnsureNative() { return NS_OK; }
@@ -299,25 +300,52 @@ NS_NewXULTreeBuilder(nsISupports* aOuter
 
     if (NS_SUCCEEDED(rv))
         rv = result->QueryInterface(aIID, aResult);
 
     NS_RELEASE(result);
     return rv;
 }
 
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeBuilder)
+
 NS_IMPL_ADDREF_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
 NS_IMPL_RELEASE_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
 
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBoxObject)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSelection)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPersistStateStore)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mObservers)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+static PRBool TraverseObservers(nsISupports* aElement, void *aData)
+{
+    nsCycleCollectionTraversalCallback *cb =
+        static_cast<nsCycleCollectionTraversalCallback*>(aData);
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mObservers[i]");
+    cb->NoteXPCOMChild(aElement);
+    return PR_TRUE;
+}
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBoxObject)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSelection)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPersistStateStore)
+    if (tmp->mObservers) {
+        tmp->mObservers->EnumerateForwards(TraverseObservers, &cb);
+    }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
 DOMCI_DATA(XULTreeBuilder, nsXULTreeBuilder)
 
-NS_INTERFACE_MAP_BEGIN(nsXULTreeBuilder)
-  NS_INTERFACE_MAP_ENTRY(nsIXULTreeBuilder)
-  NS_INTERFACE_MAP_ENTRY(nsITreeView)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XULTreeBuilder)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeBuilder)
+    NS_INTERFACE_MAP_ENTRY(nsIXULTreeBuilder)
+    NS_INTERFACE_MAP_ENTRY(nsITreeView)
+    NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XULTreeBuilder)
 NS_INTERFACE_MAP_END_INHERITING(nsXULTemplateBuilder)
 
 
 nsXULTreeBuilder::nsXULTreeBuilder()
     : mSortDirection(eDirection_Natural), mSortHints(0)
 {
 }