Bug 713865 - Don't traverse XBL and XUL protos so much, r=bent

This commit is contained in:
Olli Pettay 2011-12-29 16:34:05 +02:00
parent 3d1ecc0d66
commit fb75702799
7 changed files with 56 additions and 1 deletions

View File

@ -194,6 +194,7 @@ INCLUDES += \
-I$(srcdir)/../../xml/content/src \
-I$(srcdir)/../../../layout/xul/base/src \
-I$(srcdir)/../../xul/content/src \
-I$(srcdir)/../../xul/document/src \
-I$(srcdir)/../../html/content/src \
-I$(srcdir)/../../base/src \
-I$(srcdir)/../../xbl/src \

View File

@ -57,6 +57,9 @@
static bool sInited = 0;
PRUint32 nsCCUncollectableMarker::sGeneration = 0;
#ifdef MOZ_XUL
#include "nsXULPrototypeCache.h"
#endif
NS_IMPL_ISUPPORTS1(nsCCUncollectableMarker, nsIObserver)
@ -247,6 +250,13 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
}
}
#ifdef MOZ_XUL
nsXULPrototypeCache* xulCache = nsXULPrototypeCache::GetInstance();
if (xulCache) {
xulCache->MarkInCCGeneration(sGeneration);
}
#endif
return NS_OK;
}

View File

@ -82,6 +82,13 @@ public:
// nsIScriptGlobalObjectOwner methods
virtual nsIScriptGlobalObject* GetScriptGlobalObject();
void MarkInCCGeneration(PRUint32 aGeneration)
{
if (mDocument) {
mDocument->MarkUncollectableForCCGeneration(aGeneration);
}
}
static nsresult ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocInfo);
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsXBLDocumentInfo,

View File

@ -696,3 +696,28 @@ nsXULPrototypeCache::BeginCaching(nsIURI* aURI)
gStartupCache = startupCache;
return NS_OK;
}
static PLDHashOperator
MarkXBLInCCGeneration(nsIURI* aKey, nsRefPtr<nsXBLDocumentInfo> &aDocInfo,
void* aClosure)
{
PRUint32* gen = static_cast<PRUint32*>(aClosure);
aDocInfo->MarkInCCGeneration(*gen);
return PL_DHASH_NEXT;
}
static PLDHashOperator
MarkXULInCCGeneration(nsIURI* aKey, nsRefPtr<nsXULPrototypeDocument> &aDoc,
void* aClosure)
{
PRUint32* gen = static_cast<PRUint32*>(aClosure);
aDoc->MarkInCCGeneration(*gen);
return PL_DHASH_NEXT;
}
void
nsXULPrototypeCache::MarkInCCGeneration(PRUint32 aGeneration)
{
mXBLDocTable.Enumerate(MarkXBLInCCGeneration, &aGeneration);
mPrototypeTable.Enumerate(MarkXULInCCGeneration, &aGeneration);
}

View File

@ -159,6 +159,7 @@ public:
NS_IF_RELEASE(sInstance);
}
void MarkInCCGeneration(PRUint32 aGeneration);
protected:
friend nsresult
NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult);

View File

@ -159,7 +159,8 @@ JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
nsXULPrototypeDocument::nsXULPrototypeDocument()
: mRoot(nsnull),
mLoaded(false)
mLoaded(false),
mCCGeneration(0)
{
++gRefCnt;
}
@ -195,6 +196,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeDocument)
tmp->mPrototypeWaiters.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeDocument)
if (nsCCUncollectableMarker::InGeneration(cb, tmp->mCCGeneration)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mRoot,
nsXULPrototypeElement)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");

View File

@ -147,6 +147,11 @@ public:
// nsIScriptGlobalObjectOwner methods
virtual nsIScriptGlobalObject* GetScriptGlobalObject();
void MarkInCCGeneration(PRUint32 aCCGeneration)
{
mCCGeneration = aCCGeneration;
}
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPrototypeDocument,
nsIScriptGlobalObjectOwner)
@ -163,6 +168,8 @@ protected:
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
PRUint32 mCCGeneration;
nsXULPrototypeDocument();
virtual ~nsXULPrototypeDocument();
nsresult Init();