mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 05:10:49 +00:00
Keep the purple bit in sync with the purple buffer when suspect and forget calls are dropped on the floor. b=385548 r=graydon
This commit is contained in:
parent
1c48e99b24
commit
0ecbf11058
@ -834,8 +834,8 @@ struct nsCycleCollector
|
||||
nsCycleCollector();
|
||||
~nsCycleCollector();
|
||||
|
||||
void Suspect(nsISupports *n, PRBool current = PR_FALSE);
|
||||
void Forget(nsISupports *n);
|
||||
PRBool Suspect(nsISupports *n, PRBool current = PR_FALSE);
|
||||
PRBool Forget(nsISupports *n);
|
||||
void Allocated(void *n, size_t sz);
|
||||
void Freed(void *n);
|
||||
void Collect(PRUint32 aTryCollections = 1);
|
||||
@ -1365,7 +1365,8 @@ nsCycleCollector::CollectWhite(GCGraph &graph)
|
||||
|
||||
if (pinfo->mWasPurple) {
|
||||
nsISupports* s = NS_STATIC_CAST(nsISupports*, p);
|
||||
Forget(s);
|
||||
PRBool forgetResult = Forget(s);
|
||||
NS_ASSERTION(forgetResult, "Forget failed");
|
||||
}
|
||||
}
|
||||
else if (pinfo->mWasPurple) {
|
||||
@ -1380,7 +1381,8 @@ nsCycleCollector::CollectWhite(GCGraph &graph)
|
||||
"QI should return the same participant!");
|
||||
#endif
|
||||
cp->UnmarkPurple(s);
|
||||
Forget(s);
|
||||
PRBool forgetResult = Forget(s);
|
||||
NS_ASSERTION(forgetResult, "Forget failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1831,7 +1833,7 @@ nsCycleCollector_isScanSafe(nsISupports *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsCycleCollector::Suspect(nsISupports *n, PRBool current)
|
||||
{
|
||||
// Re-entering ::Suspect during collection used to be a fault, but
|
||||
@ -1839,20 +1841,20 @@ nsCycleCollector::Suspect(nsISupports *n, PRBool current)
|
||||
// see some spurious refcount traffic here.
|
||||
|
||||
if (mScanInProgress)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
NS_ASSERTION(nsCycleCollector_isScanSafe(n),
|
||||
"suspected a non-scansafe pointer");
|
||||
NS_ASSERTION(NS_IsMainThread(), "trying to suspect from non-main thread");
|
||||
|
||||
if (mParams.mDoNothing)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
mStats.mSuspectNode++;
|
||||
|
||||
if (nsCycleCollector_shouldSuppress(n))
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (mParams.mHookMalloc)
|
||||
@ -1870,10 +1872,12 @@ nsCycleCollector::Suspect(nsISupports *n, PRBool current)
|
||||
mBuf.Push(n);
|
||||
else
|
||||
mPurpleBuf.Put(n);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsCycleCollector::Forget(nsISupports *n)
|
||||
{
|
||||
// Re-entering ::Forget during collection used to be a fault, but
|
||||
@ -1881,12 +1885,12 @@ nsCycleCollector::Forget(nsISupports *n)
|
||||
// see some spurious refcount traffic here.
|
||||
|
||||
if (mScanInProgress)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
NS_ASSERTION(NS_IsMainThread(), "trying to forget from non-main thread");
|
||||
|
||||
if (mParams.mDoNothing)
|
||||
return;
|
||||
return PR_TRUE; // it's as good as forgotten
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
mStats.mForgetNode++;
|
||||
@ -1904,6 +1908,7 @@ nsCycleCollector::Forget(nsISupports *n)
|
||||
#endif
|
||||
|
||||
mPurpleBuf.Remove(n);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
@ -2371,27 +2376,31 @@ nsCycleCollector_forgetRuntime(PRUint32 langID)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsCycleCollector_suspect(nsISupports *n)
|
||||
{
|
||||
if (sCollector)
|
||||
sCollector->Suspect(n);
|
||||
return sCollector->Suspect(n);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsCycleCollector_suspectCurrent(nsISupports *n)
|
||||
{
|
||||
if (sCollector)
|
||||
sCollector->Suspect(n, PR_TRUE);
|
||||
if (sCollector) {
|
||||
PRBool res = sCollector->Suspect(n, PR_TRUE);
|
||||
NS_ASSERTION(res, "suspectCurrent should not fail");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsCycleCollector_forget(nsISupports *n)
|
||||
{
|
||||
if (sCollector)
|
||||
sCollector->Forget(n);
|
||||
return sCollector->Forget(n);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,9 +51,9 @@ struct nsCycleCollectionLanguageRuntime
|
||||
virtual nsCycleCollectionParticipant *ToParticipant(void *p) = 0;
|
||||
};
|
||||
|
||||
NS_COM void nsCycleCollector_suspect(nsISupports *n);
|
||||
NS_COM PRBool nsCycleCollector_suspect(nsISupports *n);
|
||||
NS_COM void nsCycleCollector_suspectCurrent(nsISupports *n);
|
||||
NS_COM void nsCycleCollector_forget(nsISupports *n);
|
||||
NS_COM PRBool nsCycleCollector_forget(nsISupports *n);
|
||||
nsresult nsCycleCollector_startup();
|
||||
NS_COM void nsCycleCollector_collect();
|
||||
void nsCycleCollector_shutdown();
|
||||
|
@ -130,7 +130,8 @@ public:
|
||||
|
||||
if (NS_UNLIKELY(purple)) {
|
||||
NS_ASSERTION(tmp != 0, "purple ISupports pointer with zero refcnt");
|
||||
nsCycleCollector_forget(owner);
|
||||
if (!nsCycleCollector_forget(owner))
|
||||
tmp |= NS_PURPLE_BIT;
|
||||
}
|
||||
|
||||
mValue = tmp + 1;
|
||||
@ -154,9 +155,12 @@ public:
|
||||
PRBool shouldBePurple = tmp > 1;
|
||||
|
||||
if (NS_UNLIKELY(shouldBePurple && !purple)) {
|
||||
nsCycleCollector_suspect(owner);
|
||||
if (!nsCycleCollector_suspect(owner))
|
||||
shouldBePurple = PR_FALSE;
|
||||
} else if (NS_UNLIKELY(tmp == 1 && purple)) {
|
||||
nsCycleCollector_forget(owner);
|
||||
if (!nsCycleCollector_forget(owner)) {
|
||||
NS_NOTREACHED("forget should not fail when reference count hits 0");
|
||||
}
|
||||
}
|
||||
|
||||
--tmp;
|
||||
|
Loading…
x
Reference in New Issue
Block a user