Bug 794694 - Make sure to trace all the gray GCthings, not only wrapper, r=mccr8

This commit is contained in:
Olli Pettay 2012-09-29 01:29:37 +03:00
parent 86c3d29fa7
commit 6f8dfd30f6
4 changed files with 31 additions and 2 deletions

View File

@ -529,7 +529,8 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXMLHttpRequest)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsXMLHttpRequest)
return tmp->IsBlack();
return tmp->
IsBlackAndDoesNotNeedTracing(static_cast<nsDOMEventTargetHelper*>(tmp));
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsXMLHttpRequest)

View File

@ -53,7 +53,7 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMEventTargetHelper)
return tmp->IsBlack();
return tmp->IsBlackAndDoesNotNeedTracing(tmp);
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMEventTargetHelper)

View File

@ -159,6 +159,12 @@ public:
*/
bool IsBlack();
/**
* Returns true if the object has a black wrapper,
* and all the GC things it is keeping alive are black too.
*/
bool IsBlackAndDoesNotNeedTracing(nsISupports* aThis);
// Only meant to be called by code that preserves a wrapper.
void SetPreservingWrapper(bool aPreserve)
{

View File

@ -24,4 +24,26 @@ nsWrapperCache::IsBlack()
return o && !xpc_IsGrayGCThing(o);
}
static void
SearchGray(void* aGCThing, const char* aName, void* aClosure)
{
bool* hasGrayObjects = static_cast<bool*>(aClosure);
if (!*hasGrayObjects && aGCThing && xpc_IsGrayGCThing(aGCThing)) {
*hasGrayObjects = true;
}
}
inline bool
nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis)
{
if (IsBlack()) {
nsXPCOMCycleCollectionParticipant* participant = nullptr;
CallQueryInterface(aThis, &participant);
bool hasGrayObjects = false;
participant->Trace(aThis, SearchGray, &hasGrayObjects);
return !hasGrayObjects;
}
return false;
}
#endif /* nsWrapperCache_h___ */