From bc5169e59ede696bab46daaac16e3d5b2bcd682f Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Fri, 6 Aug 2010 12:21:53 +0300 Subject: [PATCH] Bug 523082 - nsXULTemplateBuilder should unlink more, r=peterv --- content/base/src/nsDocument.cpp | 7 ++++++ content/xul/templates/src/nsXMLBinding.cpp | 22 +++++++++++++++++++ content/xul/templates/src/nsXMLBinding.h | 2 ++ .../templates/src/nsXULTemplateBuilder.cpp | 14 ++++++++---- .../src/nsXULTemplateQueryProcessorXML.cpp | 22 +++++++++++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index b57e62df860..c2869c5860d 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1719,6 +1719,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages) + + if (tmp->mBoxObjectTable) { + tmp->mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull); + delete tmp->mBoxObjectTable; + tmp->mBoxObjectTable = nsnull; + } + // nsDocument has a pretty complex destructor, so we're going to // assume that *most* cycles you actually want to break somewhere // else, and not unlink an awful lot here. diff --git a/content/xul/templates/src/nsXMLBinding.cpp b/content/xul/templates/src/nsXMLBinding.cpp index 15b884151d8..cbb8ee24777 100644 --- a/content/xul/templates/src/nsXMLBinding.cpp +++ b/content/xul/templates/src/nsXMLBinding.cpp @@ -41,6 +41,28 @@ NS_IMPL_ADDREF(nsXMLBindingSet) NS_IMPL_RELEASE(nsXMLBindingSet) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXMLBindingSet) + nsXMLBinding* binding = tmp->mFirst; + while (binding) { + binding->mExpr = nsnull; + binding = binding->mNext; + } +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXMLBindingSet) + nsXMLBinding* binding = tmp->mFirst; + while (binding) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsXMLBinding::mExpr"); + cb.NoteXPCOMChild(binding->mExpr); + binding = binding->mNext; + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXMLBindingSet, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXMLBindingSet, Release) + nsresult nsXMLBindingSet::AddBinding(nsIAtom* aVar, nsIDOMXPathExpression* aExpr) { diff --git a/content/xul/templates/src/nsXMLBinding.h b/content/xul/templates/src/nsXMLBinding.h index a304e1172c0..16599032dcc 100644 --- a/content/xul/templates/src/nsXMLBinding.h +++ b/content/xul/templates/src/nsXMLBinding.h @@ -39,6 +39,7 @@ #include "nsAutoPtr.h" #include "nsIAtom.h" +#include "nsCycleCollectionParticipant.h" class nsXULTemplateResultXML; class nsXMLBindingValues; @@ -88,6 +89,7 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); NS_DECL_OWNINGTHREAD + NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet) /** * Add a binding to the set diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp index e4870be1a8b..c7d72168860 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -145,7 +145,7 @@ nsXULTemplateBuilder::nsXULTemplateBuilder(void) } static PLDHashOperator -DestroyMatchList(nsISupports* aKey, nsTemplateMatch* aMatch, void* aContext) +DestroyMatchList(nsISupports* aKey, nsTemplateMatch*& aMatch, void* aContext) { nsFixedSizeAllocator* pool = static_cast(aContext); @@ -156,7 +156,7 @@ DestroyMatchList(nsISupports* aKey, nsTemplateMatch* aMatch, void* aContext) aMatch = next; } - return PL_DHASH_NEXT; + return PL_DHASH_REMOVE; } nsXULTemplateBuilder::~nsXULTemplateBuilder(void) @@ -235,8 +235,7 @@ nsXULTemplateBuilder::Uninit(PRBool aIsFinal) mQuerySets.Clear(); - mMatchMap.EnumerateRead(DestroyMatchList, &mPool); - mMatchMap.Clear(); + mMatchMap.Enumerate(DestroyMatchList, &mPool); mRootResult = nsnull; mRefVariable = nsnull; @@ -267,6 +266,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateBuilder) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDataSource) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDB) 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)); + } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateBuilder) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDataSource) diff --git a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp index 0b7bcf1d17e..9217091c5ef 100644 --- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp +++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp @@ -109,12 +109,34 @@ nsXULTemplateResultSetXML::GetNext(nsISupports **aResult) // nsXULTemplateQueryProcessorXML // +static PLDHashOperator +TraverseRuleToBindingsMap(nsISupports* aKey, nsXMLBindingSet* aMatch, void* aContext) +{ + nsCycleCollectionTraversalCallback *cb = + static_cast(aContext); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap key"); + cb->NoteXPCOMChild(aKey); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap value"); + cb->NoteNativeChild(aMatch, &NS_CYCLE_COLLECTION_NAME(nsXMLBindingSet)); + return PL_DHASH_NEXT; +} + NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML) + if (tmp->mRuleToBindingsMap.IsInitialized()) { + tmp->mRuleToBindingsMap.Clear(); + } + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEvaluator) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTemplateBuilder) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRequest) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML) + if (tmp->mRuleToBindingsMap.IsInitialized()) { + tmp->mRuleToBindingsMap.EnumerateRead(TraverseRuleToBindingsMap, &cb); + } + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEvaluator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTemplateBuilder) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRequest) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END