This commit is contained in:
peterv@propagandism.org 2008-01-29 13:42:05 -08:00
Родитель d649ebe77c
Коммит 869b3309c7
18 изменённых файлов: 73 добавлений и 151 удалений

Просмотреть файл

@ -445,10 +445,10 @@ TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
} }
static PRIntn PR_CALLBACK static PRIntn PR_CALLBACK
UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure) UnlinkProtos(nsHashKey *aKey, void *aData, void* aClosure)
{ {
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData); nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
proto->UnlinkJSObjects(); proto->Unlink();
return kHashEnumerateNext; return kHashEnumerateNext;
} }
@ -468,12 +468,10 @@ TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) {
tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nsnull);
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) {
tmp->mBindingTable->Enumerate(UnlinkProtos, nsnull);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalObject) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalObject)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END

Просмотреть файл

@ -216,7 +216,7 @@ nsXBLProtoImpl::Trace(TraceCallback aCallback, void *aClosure) const
} }
void void
nsXBLProtoImpl::UnlinkJSObjects() nsXBLProtoImpl::Unlink()
{ {
if (mClassObject) { if (mClassObject) {
DestroyMembers(nsnull); DestroyMembers(nsnull);

Просмотреть файл

@ -91,7 +91,7 @@ public:
} }
void Trace(TraceCallback aCallback, void *aClosure) const; void Trace(TraceCallback aCallback, void *aClosure) const;
void UnlinkJSObjects(); void Unlink();
nsXBLProtoImplField* FindField(const nsString& aFieldName) const; nsXBLProtoImplField* FindField(const nsString& aFieldName) const;

Просмотреть файл

@ -364,14 +364,14 @@ nsXBLPrototypeBinding::Traverse(nsCycleCollectionTraversalCallback &cb) const
} }
void void
nsXBLPrototypeBinding::UnlinkJSObjects() nsXBLPrototypeBinding::Unlink()
{ {
if (mImplementation) if (mImplementation)
mImplementation->UnlinkJSObjects(); mImplementation->Unlink();
nsXBLPrototypeHandler* curr = mPrototypeHandler; nsXBLPrototypeHandler* curr = mPrototypeHandler;
while (curr) { while (curr) {
curr->UnlinkJSObjects(); curr->Unlink();
curr = curr->GetNextHandler(); curr = curr->GetNextHandler();
} }
} }

Просмотреть файл

@ -197,7 +197,7 @@ public:
nsIContent* aElement); nsIContent* aElement);
void Traverse(nsCycleCollectionTraversalCallback &cb) const; void Traverse(nsCycleCollectionTraversalCallback &cb) const;
void UnlinkJSObjects(); void Unlink();
void Trace(TraceCallback aCallback, void *aClosure) const; void Trace(TraceCallback aCallback, void *aClosure) const;
// Static members // Static members

Просмотреть файл

@ -169,7 +169,7 @@ nsXBLPrototypeHandler::Trace(TraceCallback aCallback, void *aClosure) const
} }
void void
nsXBLPrototypeHandler::UnlinkJSObjects() nsXBLPrototypeHandler::Unlink()
{ {
ForgetCachedHandler(); ForgetCachedHandler();
} }

Просмотреть файл

@ -154,7 +154,7 @@ public:
} }
void Trace(TraceCallback aCallback, void *aClosure) const; void Trace(TraceCallback aCallback, void *aClosure) const;
void UnlinkJSObjects(); void Unlink();
public: public:
static PRUint32 gRefCnt; static PRUint32 gRefCnt;

Просмотреть файл

@ -2416,6 +2416,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXULPrototypeNode)
if (tmp->mType == nsXULPrototypeNode::eType_Element) { if (tmp->mType == nsXULPrototypeNode::eType_Element) {
static_cast<nsXULPrototypeElement*>(tmp)->Unlink(); static_cast<nsXULPrototypeElement*>(tmp)->Unlink();
} }
else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
static_cast<nsXULPrototypeScript*>(tmp)->Unlink();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode)
if (tmp->mType == nsXULPrototypeNode::eType_Element) { if (tmp->mType == nsXULPrototypeNode::eType_Element) {
@ -2449,15 +2452,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode)
script->mScriptObject.mObject) script->mScriptObject.mObject)
} }
NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN_NATIVE(nsXULPrototypeNode, AddRef) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXULPrototypeNode, AddRef)
if (tmp->mType == nsXULPrototypeNode::eType_Element) {
static_cast<nsXULPrototypeElement*>(tmp)->UnlinkJSObjects();
}
else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
static_cast<nsXULPrototypeScript*>(tmp)->UnlinkJSObjects();
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
//NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXULPrototypeNode, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -2755,18 +2750,13 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue,
} }
void void
nsXULPrototypeElement::UnlinkJSObjects() nsXULPrototypeElement::Unlink()
{ {
if (mHoldsScriptObject) { if (mHoldsScriptObject) {
nsContentUtils::DropScriptObjects(mScriptTypeID, this, nsContentUtils::DropScriptObjects(mScriptTypeID, this,
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode)); &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode));
mHoldsScriptObject = PR_FALSE; mHoldsScriptObject = PR_FALSE;
} }
}
void
nsXULPrototypeElement::Unlink()
{
mNumAttributes = 0; mNumAttributes = 0;
delete[] mAttributes; delete[] mAttributes;
mAttributes = nsnull; mAttributes = nsnull;
@ -2794,7 +2784,7 @@ nsXULPrototypeScript::nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, P
nsXULPrototypeScript::~nsXULPrototypeScript() nsXULPrototypeScript::~nsXULPrototypeScript()
{ {
UnlinkJSObjects(); Unlink();
} }
nsresult nsresult

Просмотреть файл

@ -254,7 +254,6 @@ public:
virtual ~nsXULPrototypeElement() virtual ~nsXULPrototypeElement()
{ {
UnlinkJSObjects();
Unlink(); Unlink();
NS_ASSERTION(!mChildren && mNumChildren == 0, NS_ASSERTION(!mChildren && mNumChildren == 0,
"ReleaseSubtree not called"); "ReleaseSubtree not called");
@ -290,7 +289,6 @@ public:
nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI); nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
void UnlinkJSObjects();
void Unlink(); void Unlink();
PRUint32 mNumChildren; PRUint32 mNumChildren;
@ -361,7 +359,7 @@ public:
nsIDocument* aDocument, nsIDocument* aDocument,
nsIScriptGlobalObjectOwner* aGlobalOwner); nsIScriptGlobalObjectOwner* aGlobalOwner);
void UnlinkJSObjects() void Unlink()
{ {
if (mScriptObject.mObject) { if (mScriptObject.mObject) {
nsContentUtils::DropScriptObjects(mScriptObject.mLangID, this, nsContentUtils::DropScriptObjects(mScriptObject.mLangID, this,

Просмотреть файл

@ -3841,10 +3841,9 @@ nsJSArgArray::ReleaseJSObjects()
// QueryInterface implementation for nsJSArgArray // QueryInterface implementation for nsJSArgArray
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSArgArray) NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSArgArray)
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSArgArray) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSArgArray)
tmp->ReleaseJSObjects(); tmp->ReleaseJSObjects();
NS_IMPL_CYCLE_COLLECTION_ROOT_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsJSArgArray)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

Просмотреть файл

@ -112,10 +112,9 @@ private:
// nsJSScriptTimeoutHandler // nsJSScriptTimeoutHandler
// QueryInterface implementation for nsJSScriptTimeoutHandler // QueryInterface implementation for nsJSScriptTimeoutHandler
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler) NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler)
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSScriptTimeoutHandler) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSScriptTimeoutHandler)
tmp->ReleaseJSObjects(); tmp->ReleaseJSObjects();
NS_IMPL_CYCLE_COLLECTION_ROOT_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsJSScriptTimeoutHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSScriptTimeoutHandler) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSScriptTimeoutHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArgv) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArgv)

Просмотреть файл

@ -81,34 +81,21 @@ nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext,
// until we are done with it. // until we are done with it.
NS_ASSERTION(aScopeObject && aContext, NS_ASSERTION(aScopeObject && aContext,
"EventListener with no context or scope?"); "EventListener with no context or scope?");
nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(), this, NS_HOLD_JS_OBJECTS(this, nsJSEventListener);
&NS_CYCLE_COLLECTION_NAME(nsJSEventListener),
aScopeObject, PR_FALSE);
} }
nsJSEventListener::~nsJSEventListener() nsJSEventListener::~nsJSEventListener()
{ {
if (mContext) if (mContext)
nsContentUtils::DropScriptObjects(mContext->GetScriptTypeID(), this, NS_DROP_JS_OBJECTS(this, nsJSEventListener);
&NS_CYCLE_COLLECTION_NAME(nsJSEventListener));
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSEventListener) NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSEventListener)
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSEventListener)
if (tmp->mContext &&
tmp->mContext->GetScriptTypeID() == nsIProgrammingLanguage::JAVASCRIPT) {
NS_DROP_JS_OBJECTS(tmp, nsJSEventListener);
tmp->mScopeObject = nsnull;
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSEventListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSEventListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTarget) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTarget)
if (tmp->mContext) { if (tmp->mContext) {
if (tmp->mScopeObject) { tmp->mScopeObject = nsnull;
nsContentUtils::DropScriptObjects(tmp->mContext->GetScriptTypeID(), this, NS_DROP_JS_OBJECTS(tmp, nsJSEventListener);
&NS_CYCLE_COLLECTION_NAME(nsJSEventListener));
tmp->mScopeObject = nsnull;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
} }
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END

Просмотреть файл

@ -679,7 +679,7 @@ nsXPConnect::ToParticipant(void *p)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsXPConnect::RootAndUnlinkJSObjects(void *p) nsXPConnect::Root(void *p)
{ {
return NS_OK; return NS_OK;
} }
@ -937,7 +937,7 @@ nsXPConnect::GetRequestDepth(JSContext* cx)
class JSContextParticipant : public nsCycleCollectionParticipant class JSContextParticipant : public nsCycleCollectionParticipant
{ {
public: public:
NS_IMETHOD RootAndUnlinkJSObjects(void *n) NS_IMETHOD Root(void *n)
{ {
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -497,7 +497,7 @@ public:
nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info); nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
// nsCycleCollectionParticipant // nsCycleCollectionParticipant
NS_IMETHOD RootAndUnlinkJSObjects(void *p); NS_IMETHOD Root(void *p);
NS_IMETHOD Unlink(void *p); NS_IMETHOD Unlink(void *p);
NS_IMETHOD Unroot(void *p); NS_IMETHOD Unroot(void *p);
NS_IMETHOD Traverse(void *p, NS_IMETHOD Traverse(void *p,
@ -2488,14 +2488,8 @@ public:
NS_DECL_NSIXPCONNECTWRAPPEDJS NS_DECL_NSIXPCONNECTWRAPPEDJS
NS_DECL_NSISUPPORTSWEAKREFERENCE NS_DECL_NSISUPPORTSWEAKREFERENCE
NS_DECL_NSIPROPERTYBAG NS_DECL_NSIPROPERTYBAG
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXPCWrappedJS,
class NS_CYCLE_COLLECTION_INNERCLASS nsIXPConnectWrappedJS)
: public nsXPCOMCycleCollectionParticipant
{
NS_IMETHOD RootAndUnlinkJSObjects(void *p);
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(nsXPCWrappedJS, nsIXPConnectWrappedJS)
};
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(nsXPCWrappedJS) NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(nsXPCWrappedJS)
NS_IMETHOD CallMethod(PRUint16 methodIndex, NS_IMETHOD CallMethod(PRUint16 methodIndex,

Просмотреть файл

@ -112,35 +112,17 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
return NS_OK; return NS_OK;
} }
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXPCWrappedJS)
if(tmp->mRoot && !tmp->mRoot->HasWeakReferences() && tmp->IsValid())
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if(rt)
{
if(tmp->mRoot == tmp)
{
// remove this root wrapper from the map
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
if(map)
{
XPCAutoLock lock(rt->GetMapLock());
map->Remove(tmp);
}
}
if(tmp->mRefCnt > 1)
tmp->RemoveFromRootSet(rt->GetJSRuntime());
}
tmp->mJSObj = nsnull;
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPCWrappedJS) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPCWrappedJS)
if(tmp->mRoot && !tmp->mRoot->HasWeakReferences()) if(tmp->mRoot && !tmp->mRoot->HasWeakReferences())
{ {
tmp->Unlink(); tmp->Unlink();
if(tmp->IsValid())
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if(tmp->mRefCnt > 1)
tmp->RemoveFromRootSet(rt->GetJSRuntime());
tmp->mJSObj = nsnull;
}
} }
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -169,6 +151,9 @@ nsXPCWrappedJS::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_IMETHODIMP NS_IMETHODIMP
nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr) nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{ {
if(!IsValid())
return NS_ERROR_UNEXPECTED;
if(nsnull == aInstancePtr) if(nsnull == aInstancePtr)
{ {
NS_PRECONDITION(0, "null pointer"); NS_PRECONDITION(0, "null pointer");
@ -188,9 +173,6 @@ nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_OK; return NS_OK;
} }
if(!IsValid())
return NS_ERROR_UNEXPECTED;
// Always check for this first so that our 'outer' can get this interface // Always check for this first so that our 'outer' can get this interface
// from us without recurring into a call to the outer's QI! // from us without recurring into a call to the outer's QI!
if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS))) if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
@ -471,9 +453,17 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
{ {
// Let the nsWeakReference object (if present) know of our demise. // Let the nsWeakReference object (if present) know of our demise.
ClearWeakReferences(); ClearWeakReferences();
}
Unlink();
}
// Remove this root wrapper from the map void
XPCJSRuntime* rt = nsXPConnect::GetRuntime(); nsXPCWrappedJS::Unlink()
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if(mRoot == this)
{
// remove this root wrapper from the map
if(rt) if(rt)
{ {
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap(); JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
@ -484,13 +474,7 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
} }
} }
} }
Unlink(); else if(mRoot)
}
void
nsXPCWrappedJS::Unlink()
{
if(mRoot != this && mRoot)
{ {
// unlink this wrapper // unlink this wrapper
nsXPCWrappedJS* cur = mRoot; nsXPCWrappedJS* cur = mRoot;
@ -513,7 +497,6 @@ nsXPCWrappedJS::Unlink()
NS_IF_RELEASE(mClass); NS_IF_RELEASE(mClass);
if (mOuter) if (mOuter)
{ {
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
if (rt && rt->GetThreadRunningGC()) if (rt && rt->GetThreadRunningGC())
{ {
rt->DeferredRelease(mOuter); rt->DeferredRelease(mOuter);

Просмотреть файл

@ -878,8 +878,8 @@ struct nsCycleCollector
void SelectPurple(); void SelectPurple();
void MarkRoots(GCGraphBuilder &builder); void MarkRoots(GCGraphBuilder &builder);
void ScanRoots(); void ScanRoots();
void RootWhite(); void CollectWhite();
PRBool CollectWhite(); // returns whether anything was collected PRBool UnrootWhite(); // returns whether anything was collected
nsCycleCollector(); nsCycleCollector();
~nsCycleCollector(); ~nsCycleCollector();
@ -1525,7 +1525,7 @@ nsCycleCollector::ScanRoots()
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
void void
nsCycleCollector::RootWhite() nsCycleCollector::CollectWhite()
{ {
// Explanation of "somewhat modified": we have no way to collect the // Explanation of "somewhat modified": we have no way to collect the
// set of whites "all at once", we have to ask each of them to drop // set of whites "all at once", we have to ask each of them to drop
@ -1562,17 +1562,11 @@ nsCycleCollector::RootWhite()
PRUint32 i, count = mBuf.GetSize(); PRUint32 i, count = mBuf.GetSize();
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i)); PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
rv = pinfo->mParticipant->RootAndUnlinkJSObjects(pinfo->mPointer); rv = pinfo->mParticipant->Root(pinfo->mPointer);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
Fault("Failed root call while unlinking", pinfo); Fault("Failed root call while unlinking", pinfo);
} }
}
PRBool
nsCycleCollector::CollectWhite()
{
nsresult rv;
PRUint32 i, count = mBuf.GetSize();
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i)); PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
rv = pinfo->mParticipant->Unlink(pinfo->mPointer); rv = pinfo->mParticipant->Unlink(pinfo->mPointer);
@ -1588,7 +1582,13 @@ nsCycleCollector::CollectWhite()
#endif #endif
} }
} }
}
PRBool
nsCycleCollector::UnrootWhite()
{
nsresult rv;
PRUint32 i, count = mBuf.GetSize();
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i)); PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
rv = pinfo->mParticipant->Unroot(pinfo->mPointer); rv = pinfo->mParticipant->Unroot(pinfo->mPointer);
@ -2286,7 +2286,7 @@ nsCycleCollector::BeginCollection()
#ifdef COLLECT_TIME_DEBUG #ifdef COLLECT_TIME_DEBUG
now = PR_Now(); now = PR_Now();
#endif #endif
RootWhite(); CollectWhite();
#ifdef COLLECT_TIME_DEBUG #ifdef COLLECT_TIME_DEBUG
printf("cc: CollectWhite() took %lldms\n", printf("cc: CollectWhite() took %lldms\n",
@ -2300,7 +2300,7 @@ nsCycleCollector::BeginCollection()
PRBool PRBool
nsCycleCollector::FinishCollection() nsCycleCollector::FinishCollection()
{ {
PRBool collected = CollectWhite(); PRBool collected = UnrootWhite();
#ifdef DEBUG_CC #ifdef DEBUG_CC
mStats.mCollection++; mStats.mCollection++;

Просмотреть файл

@ -54,7 +54,7 @@ nsScriptObjectTracer::TraverseScriptObjects(void *p,
} }
nsresult nsresult
nsXPCOMCycleCollectionParticipant::RootAndUnlinkJSObjects(void *p) nsXPCOMCycleCollectionParticipant::Root(void *p)
{ {
nsISupports *s = static_cast<nsISupports*>(p); nsISupports *s = static_cast<nsISupports*>(p);
NS_ADDREF(s); NS_ADDREF(s);

Просмотреть файл

@ -122,7 +122,7 @@ public:
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0; NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
NS_IMETHOD RootAndUnlinkJSObjects(void *p) = 0; NS_IMETHOD Root(void *p) = 0;
NS_IMETHOD Unlink(void *p) = 0; NS_IMETHOD Unlink(void *p) = 0;
NS_IMETHOD Unroot(void *p) = 0; NS_IMETHOD Unroot(void *p) = 0;
}; };
@ -150,7 +150,7 @@ class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
public: public:
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
NS_IMETHOD RootAndUnlinkJSObjects(void *p); NS_IMETHOD Root(void *p);
NS_IMETHOD Unlink(void *p); NS_IMETHOD Unlink(void *p);
NS_IMETHOD Unroot(void *p); NS_IMETHOD Unroot(void *p);
@ -228,31 +228,6 @@ public:
#define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \ #define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \
NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj) NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
///////////////////////////////////////////////////////////////////////////////
// Helpers for implementing nsCycleCollectionParticipant::RootAndUnlinkJSObjects
///////////////////////////////////////////////////////////////////////////////
#define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(_class) \
NS_IMETHODIMP \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
{ \
nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \
"not the nsISupports pointer we expect"); \
nsXPCOMCycleCollectionParticipant::RootAndUnlinkJSObjects(s); \
_class *tmp = Downcast(s);
#define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN_NATIVE(_class, _root_function) \
NS_IMETHODIMP \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
{ \
_class *tmp = static_cast<_class*>(p); \
tmp->_root_function();
#define NS_IMPL_CYCLE_COLLECTION_ROOT_END \
return NS_OK; \
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Helpers for implementing nsCycleCollectionParticipant::Unlink // Helpers for implementing nsCycleCollectionParticipant::Unlink
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -479,13 +454,13 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
// Cycle collector helper for classes that don't want to unlink anything. // Cycle collector helper for classes that don't want to unlink anything.
// Note: if this is used a lot it might make sense to have a base class that // Note: if this is used a lot it might make sense to have a base class that
// doesn't do anything in RootAndUnlinkJSObjects/Unlink/Unroot. // doesn't do anything in Root/Unlink/Unroot.
#define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class) \ NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class) \
NS_IMETHOD RootAndUnlinkJSObjects(void *p) \ NS_IMETHOD Root(void *p) \
{ \ { \
return NS_OK; \ return NS_OK; \
} \ } \
@ -504,7 +479,6 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
NS_IMETHOD RootAndUnlinkJSObjects(void *p); \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \ NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \ NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
}; \ }; \
@ -561,7 +535,7 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \ #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
public: \ public: \
NS_IMETHOD RootAndUnlinkJSObjects(void *n); \ NS_IMETHOD Root(void *n); \
NS_IMETHOD Unlink(void *n); \ NS_IMETHOD Unlink(void *n); \
NS_IMETHOD Unroot(void *n); \ NS_IMETHOD Unroot(void *n); \
NS_IMETHOD Traverse(void *n, \ NS_IMETHOD Traverse(void *n, \
@ -586,7 +560,7 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
#define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \ #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
NS_IMETHODIMP \ NS_IMETHODIMP \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p) \
{ \ { \
_class *tmp = static_cast<_class*>(p); \ _class *tmp = static_cast<_class*>(p); \
tmp->_root_function(); \ tmp->_root_function(); \