Bug 915488 - Make CC participant's Root, Unroot and Unlink methods infallible. r=smaug

This commit is contained in:
Andrew McCreight 2013-09-11 18:57:53 -07:00
parent b97a6ad1e1
commit bb3f012209
8 changed files with 30 additions and 52 deletions

View File

@ -74,7 +74,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLObjectElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(HTMLObjectElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLObjectElement, Element)

View File

@ -41,12 +41,11 @@ xpc_OkToHandOutWrapper(nsWrapperCache *cache)
NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative)
NS_IMETHODIMP
NS_IMETHODIMP_(void)
NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Unlink(void *p)
{
XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);
tmp->ExpireWrapper();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -2191,8 +2191,8 @@ public:
: public nsXPCOMCycleCollectionParticipant
{
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(XPCWrappedNative, XPCWrappedNative)
NS_IMETHOD Root(void *p) { return NS_OK; }
NS_IMETHOD Unroot(void *p) { return NS_OK; }
NS_IMETHOD_(void) Root(void *p) { }
NS_IMETHOD_(void) Unroot(void *p) { }
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(XPCWrappedNative)
};
NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(XPCWrappedNative);

View File

@ -28,19 +28,16 @@ namespace mozilla {
class JSGCThingParticipant: public nsCycleCollectionParticipant
{
public:
NS_IMETHOD Root(void *n)
NS_IMETHOD_(void) Root(void *n)
{
return NS_OK;
}
NS_IMETHOD Unlink(void *n)
NS_IMETHOD_(void) Unlink(void *n)
{
return NS_OK;
}
NS_IMETHOD Unroot(void *n)
NS_IMETHOD_(void) Unroot(void *n)
{
return NS_OK;
}
NS_IMETHOD_(void) DeleteCycleCollectable(void *n)
@ -55,19 +52,16 @@ class JSZoneParticipant : public nsCycleCollectionParticipant
public:
MOZ_CONSTEXPR JSZoneParticipant(): nsCycleCollectionParticipant() {}
NS_IMETHOD Root(void *p)
NS_IMETHOD_(void) Root(void *p)
{
return NS_OK;
}
NS_IMETHOD Unlink(void *p)
NS_IMETHOD_(void) Unlink(void *p)
{
return NS_OK;
}
NS_IMETHOD Unroot(void *p)
NS_IMETHOD_(void) Unroot(void *p)
{
return NS_OK;
}
NS_IMETHOD_(void) DeleteCycleCollectable(void *n)

View File

@ -72,7 +72,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \
{ \
public: \
NS_IMETHOD Unlink(void *p); \
NS_IMETHOD_(void) Unlink(void *p); \
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); \
NS_IMETHOD_(void) DeleteCycleCollectable(void* p) \
{ \

View File

@ -2319,7 +2319,6 @@ nsCycleCollector::CollectWhite()
// - Unlink(whites), which drops outgoing links on each white.
// - Unroot(whites), which returns the whites to normal GC.
nsresult rv;
TimeLog timeLog;
MOZ_ASSERT(mWhiteNodes->IsEmpty(),
@ -2334,11 +2333,8 @@ nsCycleCollector::CollectWhite()
PtrInfo *pinfo = etor.GetNext();
if (pinfo->mColor == white) {
mWhiteNodes->AppendElement(pinfo);
rv = pinfo->mParticipant->Root(pinfo->mPointer);
if (NS_FAILED(rv)) {
Fault("Failed root call while unlinking", pinfo);
mWhiteNodes->RemoveElementAt(mWhiteNodes->Length() - 1);
} else if (pinfo->mRefCount == 0) {
pinfo->mParticipant->Root(pinfo->mPointer);
if (pinfo->mRefCount == 0) {
// only JS objects have a refcount of 0
++numWhiteGCed;
}
@ -2367,24 +2363,19 @@ nsCycleCollector::CollectWhite()
mJSRuntime->SetObjectToUnlink(pinfo->mPointer);
}
#endif
rv = pinfo->mParticipant->Unlink(pinfo->mPointer);
pinfo->mParticipant->Unlink(pinfo->mPointer);
#ifdef DEBUG
if (mJSRuntime) {
mJSRuntime->SetObjectToUnlink(nullptr);
mJSRuntime->AssertNoObjectsToTrace(pinfo->mPointer);
}
#endif
if (NS_FAILED(rv)) {
Fault("Failed unlink call while unlinking", pinfo);
}
}
timeLog.Checkpoint("CollectWhite::Unlink");
for (uint32_t i = 0; i < count; ++i) {
PtrInfo *pinfo = mWhiteNodes->ElementAt(i);
rv = pinfo->mParticipant->Unroot(pinfo->mPointer);
if (NS_FAILED(rv))
Fault("Failed unroot call while unlinking", pinfo);
pinfo->mParticipant->Unroot(pinfo->mPointer);
}
timeLog.Checkpoint("CollectWhite::Unroot");

View File

@ -23,20 +23,18 @@ nsScriptObjectTracer::NoteJSChild(void *aScriptThing, const char *name,
cb->NoteJSChild(aScriptThing);
}
NS_IMETHODIMP
NS_IMETHODIMP_(void)
nsXPCOMCycleCollectionParticipant::Root(void *p)
{
nsISupports *s = static_cast<nsISupports*>(p);
NS_ADDREF(s);
return NS_OK;
}
NS_IMETHODIMP
NS_IMETHODIMP_(void)
nsXPCOMCycleCollectionParticipant::Unroot(void *p)
{
nsISupports *s = static_cast<nsISupports*>(p);
NS_RELEASE(s);
return NS_OK;
}
// We define a default trace function because some participants don't need

View File

@ -95,9 +95,9 @@ public:
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
NS_IMETHOD Root(void *p) = 0;
NS_IMETHOD Unlink(void *p) = 0;
NS_IMETHOD Unroot(void *p) = 0;
NS_IMETHOD_(void) Root(void *p) = 0;
NS_IMETHOD_(void) Unlink(void *p) = 0;
NS_IMETHOD_(void) Unroot(void *p) = 0;
// If CanSkip returns true, p is removed from the purple buffer during
// a call to nsCycleCollector_forgetSkippable().
@ -168,8 +168,8 @@ public:
MOZ_CONSTEXPR nsXPCOMCycleCollectionParticipant() : nsScriptObjectTracer(false) {}
MOZ_CONSTEXPR nsXPCOMCycleCollectionParticipant(bool aSkip) : nsScriptObjectTracer(aSkip) {}
NS_IMETHOD Root(void *p);
NS_IMETHOD Unroot(void *p);
NS_IMETHOD_(void) Root(void *p);
NS_IMETHOD_(void) Unroot(void *p);
NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure);
@ -326,7 +326,7 @@ T* DowncastCCParticipant(void *p)
///////////////////////////////////////////////////////////////////////////////
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
NS_IMETHODIMP \
NS_IMETHODIMP_(void) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
{ \
_class *tmp = DowncastCCParticipant<_class >(p);
@ -341,14 +341,12 @@ T* DowncastCCParticipant(void *p)
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
(void)tmp; \
return NS_OK; \
}
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(_base_class) \
nsISupports *s = static_cast<nsISupports*>(p); \
NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s); \
(void)tmp; \
return NS_OK; \
}
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
@ -476,7 +474,7 @@ public: \
#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
NS_IMETHOD Unlink(void *p);
NS_IMETHOD_(void) Unlink(void *p);
#define NS_PARTICIPANT_AS(type, participant) \
const_cast<type*>(reinterpret_cast<const type*>(participant))
@ -599,7 +597,7 @@ public: \
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
NS_IMETHOD Unlink(void *p);
NS_IMETHOD_(void) Unlink(void *p);
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \
@ -640,9 +638,9 @@ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
public: \
NS_IMETHOD Root(void *n); \
NS_IMETHOD Unlink(void *n); \
NS_IMETHOD Unroot(void *n); \
NS_IMETHOD_(void) Root(void *n); \
NS_IMETHOD_(void) Unlink(void *n); \
NS_IMETHOD_(void) Unroot(void *n); \
NS_IMETHOD Traverse(void *n, nsCycleCollectionTraversalCallback &cb); \
NS_IMETHOD_(void) DeleteCycleCollectable(void *n) \
{ \
@ -691,21 +689,19 @@ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
#define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
NS_IMETHODIMP \
NS_IMETHODIMP_(void) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p) \
{ \
_class *tmp = static_cast<_class*>(p); \
tmp->_root_function(); \
return NS_OK; \
}
#define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function) \
NS_IMETHODIMP \
NS_IMETHODIMP_(void) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p) \
{ \
_class *tmp = static_cast<_class*>(p); \
tmp->_unroot_function(); \
return NS_OK; \
}
// NS_IMPL_CYCLE_COLLECTION_0 is not defined because most of the time it doesn't