mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix for bug 407034 (JS_Assert "!rt->gcRunning" unbinding link elements in cycle collector with JS protocol handlers), r/sr=dbaron.
This commit is contained in:
parent
334071547a
commit
6d9909d3c6
@ -445,10 +445,10 @@ TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
}
|
||||
|
||||
static PRIntn PR_CALLBACK
|
||||
UnlinkProtos(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
|
||||
proto->Unlink();
|
||||
proto->UnlinkJSObjects();
|
||||
return kHashEnumerateNext;
|
||||
}
|
||||
|
||||
@ -468,10 +468,12 @@ TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsXBLDocumentInfo)
|
||||
if (tmp->mBindingTable) {
|
||||
tmp->mBindingTable->Enumerate(UnlinkProtos, nsnull);
|
||||
tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nsnull);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -216,7 +216,7 @@ nsXBLProtoImpl::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLProtoImpl::Unlink()
|
||||
nsXBLProtoImpl::UnlinkJSObjects()
|
||||
{
|
||||
if (mClassObject) {
|
||||
DestroyMembers(nsnull);
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
void Unlink();
|
||||
void UnlinkJSObjects();
|
||||
|
||||
nsXBLProtoImplField* FindField(const nsString& aFieldName) const;
|
||||
|
||||
|
@ -364,14 +364,14 @@ nsXBLPrototypeBinding::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeBinding::Unlink()
|
||||
nsXBLPrototypeBinding::UnlinkJSObjects()
|
||||
{
|
||||
if (mImplementation)
|
||||
mImplementation->Unlink();
|
||||
mImplementation->UnlinkJSObjects();
|
||||
|
||||
nsXBLPrototypeHandler* curr = mPrototypeHandler;
|
||||
while (curr) {
|
||||
curr->Unlink();
|
||||
curr->UnlinkJSObjects();
|
||||
curr = curr->GetNextHandler();
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public:
|
||||
nsIContent* aElement);
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb) const;
|
||||
void Unlink();
|
||||
void UnlinkJSObjects();
|
||||
void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
|
||||
// Static members
|
||||
|
@ -169,7 +169,7 @@ nsXBLPrototypeHandler::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeHandler::Unlink()
|
||||
nsXBLPrototypeHandler::UnlinkJSObjects()
|
||||
{
|
||||
ForgetCachedHandler();
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public:
|
||||
}
|
||||
|
||||
void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
void Unlink();
|
||||
void UnlinkJSObjects();
|
||||
|
||||
public:
|
||||
static PRUint32 gRefCnt;
|
||||
|
@ -2416,9 +2416,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXULPrototypeNode)
|
||||
if (tmp->mType == nsXULPrototypeNode::eType_Element) {
|
||||
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_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode)
|
||||
if (tmp->mType == nsXULPrototypeNode::eType_Element) {
|
||||
@ -2452,7 +2449,15 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode)
|
||||
script->mScriptObject.mObject)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXULPrototypeNode, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN_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)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -2750,13 +2755,18 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue,
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeElement::Unlink()
|
||||
nsXULPrototypeElement::UnlinkJSObjects()
|
||||
{
|
||||
if (mHoldsScriptObject) {
|
||||
nsContentUtils::DropScriptObjects(mScriptTypeID, this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode));
|
||||
mHoldsScriptObject = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeElement::Unlink()
|
||||
{
|
||||
mNumAttributes = 0;
|
||||
delete[] mAttributes;
|
||||
mAttributes = nsnull;
|
||||
@ -2784,7 +2794,7 @@ nsXULPrototypeScript::nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, P
|
||||
|
||||
nsXULPrototypeScript::~nsXULPrototypeScript()
|
||||
{
|
||||
Unlink();
|
||||
UnlinkJSObjects();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -254,6 +254,7 @@ public:
|
||||
|
||||
virtual ~nsXULPrototypeElement()
|
||||
{
|
||||
UnlinkJSObjects();
|
||||
Unlink();
|
||||
NS_ASSERTION(!mChildren && mNumChildren == 0,
|
||||
"ReleaseSubtree not called");
|
||||
@ -289,6 +290,7 @@ public:
|
||||
|
||||
nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
|
||||
|
||||
void UnlinkJSObjects();
|
||||
void Unlink();
|
||||
|
||||
PRUint32 mNumChildren;
|
||||
@ -359,7 +361,7 @@ public:
|
||||
nsIDocument* aDocument,
|
||||
nsIScriptGlobalObjectOwner* aGlobalOwner);
|
||||
|
||||
void Unlink()
|
||||
void UnlinkJSObjects()
|
||||
{
|
||||
if (mScriptObject.mObject) {
|
||||
nsContentUtils::DropScriptObjects(mScriptObject.mLangID, this,
|
||||
|
@ -3841,9 +3841,10 @@ nsJSArgArray::ReleaseJSObjects()
|
||||
|
||||
// QueryInterface implementation for nsJSArgArray
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSArgArray)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSArgArray)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSArgArray)
|
||||
tmp->ReleaseJSObjects();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsJSArgArray)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
@ -112,9 +112,10 @@ private:
|
||||
// nsJSScriptTimeoutHandler
|
||||
// QueryInterface implementation for nsJSScriptTimeoutHandler
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSScriptTimeoutHandler)
|
||||
tmp->ReleaseJSObjects();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArgv)
|
||||
|
@ -81,21 +81,34 @@ nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext,
|
||||
// until we are done with it.
|
||||
NS_ASSERTION(aScopeObject && aContext,
|
||||
"EventListener with no context or scope?");
|
||||
NS_HOLD_JS_OBJECTS(this, nsJSEventListener);
|
||||
nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(), this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsJSEventListener),
|
||||
aScopeObject, PR_FALSE);
|
||||
}
|
||||
|
||||
nsJSEventListener::~nsJSEventListener()
|
||||
{
|
||||
if (mContext)
|
||||
NS_DROP_JS_OBJECTS(this, nsJSEventListener);
|
||||
nsContentUtils::DropScriptObjects(mContext->GetScriptTypeID(), this,
|
||||
&NS_CYCLE_COLLECTION_NAME(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_NSCOMPTR(mTarget)
|
||||
if (tmp->mContext) {
|
||||
tmp->mScopeObject = nsnull;
|
||||
NS_DROP_JS_OBJECTS(tmp, nsJSEventListener);
|
||||
if (tmp->mScopeObject) {
|
||||
nsContentUtils::DropScriptObjects(tmp->mContext->GetScriptTypeID(), this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsJSEventListener));
|
||||
tmp->mScopeObject = nsnull;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -679,7 +679,7 @@ nsXPConnect::ToParticipant(void *p)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::Root(void *p)
|
||||
nsXPConnect::RootAndUnlinkJSObjects(void *p)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
@ -937,7 +937,7 @@ nsXPConnect::GetRequestDepth(JSContext* cx)
|
||||
class JSContextParticipant : public nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Root(void *n)
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -497,7 +497,7 @@ public:
|
||||
nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
|
||||
|
||||
// nsCycleCollectionParticipant
|
||||
NS_IMETHOD Root(void *p);
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *p);
|
||||
NS_IMETHOD Unlink(void *p);
|
||||
NS_IMETHOD Unroot(void *p);
|
||||
NS_IMETHOD Traverse(void *p,
|
||||
@ -2488,8 +2488,14 @@ public:
|
||||
NS_DECL_NSIXPCONNECTWRAPPEDJS
|
||||
NS_DECL_NSISUPPORTSWEAKREFERENCE
|
||||
NS_DECL_NSIPROPERTYBAG
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXPCWrappedJS,
|
||||
nsIXPConnectWrappedJS)
|
||||
|
||||
class NS_CYCLE_COLLECTION_INNERCLASS
|
||||
: 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_IMETHOD CallMethod(PRUint16 methodIndex,
|
||||
|
@ -112,17 +112,35 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
|
||||
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)
|
||||
if(tmp->mRoot && !tmp->mRoot->HasWeakReferences())
|
||||
{
|
||||
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
|
||||
|
||||
@ -151,9 +169,6 @@ nsXPCWrappedJS::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
NS_IMETHODIMP
|
||||
nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if(!IsValid())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if(nsnull == aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(0, "null pointer");
|
||||
@ -173,6 +188,9 @@ nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if(!IsValid())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// 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!
|
||||
if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
|
||||
@ -453,17 +471,9 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
|
||||
{
|
||||
// Let the nsWeakReference object (if present) know of our demise.
|
||||
ClearWeakReferences();
|
||||
}
|
||||
Unlink();
|
||||
}
|
||||
|
||||
void
|
||||
nsXPCWrappedJS::Unlink()
|
||||
{
|
||||
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
|
||||
if(mRoot == this)
|
||||
{
|
||||
// remove this root wrapper from the map
|
||||
// Remove this root wrapper from the map
|
||||
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
|
||||
if(rt)
|
||||
{
|
||||
JSObject2WrappedJSMap* map = rt->GetWrappedJSMap();
|
||||
@ -474,7 +484,13 @@ nsXPCWrappedJS::Unlink()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mRoot)
|
||||
Unlink();
|
||||
}
|
||||
|
||||
void
|
||||
nsXPCWrappedJS::Unlink()
|
||||
{
|
||||
if(mRoot != this && mRoot)
|
||||
{
|
||||
// unlink this wrapper
|
||||
nsXPCWrappedJS* cur = mRoot;
|
||||
@ -492,20 +508,18 @@ nsXPCWrappedJS::Unlink()
|
||||
NS_RELEASE(mRoot);
|
||||
}
|
||||
|
||||
if(IsValid())
|
||||
NS_IF_RELEASE(mClass);
|
||||
if (mOuter)
|
||||
{
|
||||
NS_IF_RELEASE(mClass);
|
||||
if (mOuter)
|
||||
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
|
||||
if (rt && rt->GetThreadRunningGC())
|
||||
{
|
||||
if (rt && rt->GetThreadRunningGC())
|
||||
{
|
||||
rt->DeferredRelease(mOuter);
|
||||
mOuter = nsnull;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_RELEASE(mOuter);
|
||||
}
|
||||
rt->DeferredRelease(mOuter);
|
||||
mOuter = nsnull;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_RELEASE(mOuter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -878,8 +878,8 @@ struct nsCycleCollector
|
||||
void SelectPurple();
|
||||
void MarkRoots(GCGraphBuilder &builder);
|
||||
void ScanRoots();
|
||||
void CollectWhite();
|
||||
PRBool UnrootWhite(); // returns whether anything was collected
|
||||
void RootWhite();
|
||||
PRBool CollectWhite(); // returns whether anything was collected
|
||||
|
||||
nsCycleCollector();
|
||||
~nsCycleCollector();
|
||||
@ -1525,7 +1525,7 @@ nsCycleCollector::ScanRoots()
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
nsCycleCollector::CollectWhite()
|
||||
nsCycleCollector::RootWhite()
|
||||
{
|
||||
// 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
|
||||
@ -1562,11 +1562,17 @@ nsCycleCollector::CollectWhite()
|
||||
PRUint32 i, count = mBuf.GetSize();
|
||||
for (i = 0; i < count; ++i) {
|
||||
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
|
||||
rv = pinfo->mParticipant->Root(pinfo->mPointer);
|
||||
rv = pinfo->mParticipant->RootAndUnlinkJSObjects(pinfo->mPointer);
|
||||
if (NS_FAILED(rv))
|
||||
Fault("Failed root call while unlinking", pinfo);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCycleCollector::CollectWhite()
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 i, count = mBuf.GetSize();
|
||||
for (i = 0; i < count; ++i) {
|
||||
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
|
||||
rv = pinfo->mParticipant->Unlink(pinfo->mPointer);
|
||||
@ -1582,13 +1588,7 @@ nsCycleCollector::CollectWhite()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCycleCollector::UnrootWhite()
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 i, count = mBuf.GetSize();
|
||||
for (i = 0; i < count; ++i) {
|
||||
PtrInfo *pinfo = static_cast<PtrInfo*>(mBuf.ObjectAt(i));
|
||||
rv = pinfo->mParticipant->Unroot(pinfo->mPointer);
|
||||
@ -2286,7 +2286,7 @@ nsCycleCollector::BeginCollection()
|
||||
#ifdef COLLECT_TIME_DEBUG
|
||||
now = PR_Now();
|
||||
#endif
|
||||
CollectWhite();
|
||||
RootWhite();
|
||||
|
||||
#ifdef COLLECT_TIME_DEBUG
|
||||
printf("cc: CollectWhite() took %lldms\n",
|
||||
@ -2300,7 +2300,7 @@ nsCycleCollector::BeginCollection()
|
||||
PRBool
|
||||
nsCycleCollector::FinishCollection()
|
||||
{
|
||||
PRBool collected = UnrootWhite();
|
||||
PRBool collected = CollectWhite();
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
mStats.mCollection++;
|
||||
|
@ -54,7 +54,7 @@ nsScriptObjectTracer::TraverseScriptObjects(void *p,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXPCOMCycleCollectionParticipant::Root(void *p)
|
||||
nsXPCOMCycleCollectionParticipant::RootAndUnlinkJSObjects(void *p)
|
||||
{
|
||||
nsISupports *s = static_cast<nsISupports*>(p);
|
||||
NS_ADDREF(s);
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
|
||||
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
|
||||
|
||||
NS_IMETHOD Root(void *p) = 0;
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *p) = 0;
|
||||
NS_IMETHOD Unlink(void *p) = 0;
|
||||
NS_IMETHOD Unroot(void *p) = 0;
|
||||
};
|
||||
@ -150,7 +150,7 @@ class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
|
||||
public:
|
||||
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
NS_IMETHOD Root(void *p);
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *p);
|
||||
NS_IMETHOD Unlink(void *p);
|
||||
NS_IMETHOD Unroot(void *p);
|
||||
|
||||
@ -228,6 +228,31 @@ public:
|
||||
#define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \
|
||||
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
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -454,13 +479,13 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
|
||||
|
||||
// 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
|
||||
// doesn't do anything in Root/Unlink/Unroot.
|
||||
// doesn't do anything in RootAndUnlinkJSObjects/Unlink/Unroot.
|
||||
#define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class) \
|
||||
class NS_CYCLE_COLLECTION_INNERCLASS \
|
||||
: public nsXPCOMCycleCollectionParticipant \
|
||||
{ \
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class) \
|
||||
NS_IMETHOD Root(void *p) \
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *p) \
|
||||
{ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
@ -479,6 +504,7 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
|
||||
class NS_CYCLE_COLLECTION_INNERCLASS \
|
||||
: public nsXPCOMCycleCollectionParticipant \
|
||||
{ \
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *p); \
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
|
||||
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
|
||||
}; \
|
||||
@ -535,7 +561,7 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
|
||||
|
||||
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
|
||||
public: \
|
||||
NS_IMETHOD Root(void *n); \
|
||||
NS_IMETHOD RootAndUnlinkJSObjects(void *n); \
|
||||
NS_IMETHOD Unlink(void *n); \
|
||||
NS_IMETHOD Unroot(void *n); \
|
||||
NS_IMETHOD Traverse(void *n, \
|
||||
@ -560,7 +586,7 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
|
||||
NS_IMETHODIMP \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p) \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
|
||||
{ \
|
||||
_class *tmp = static_cast<_class*>(p); \
|
||||
tmp->_root_function(); \
|
||||
|
Loading…
Reference in New Issue
Block a user