Bug 616262 - Avoid cycle collection participant global variables adding static initializers. r=smaug,r=mccr8,r=Waldo

This commit is contained in:
Mike Hommey 2012-06-04 08:30:26 +02:00
Родитель 6505be978b
Коммит bda3a28b5d
22 изменённых файлов: 403 добавлений и 247 удалений

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

@ -88,7 +88,7 @@ AccEvent::CreateXPCOMObject()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// AccEvent cycle collection // AccEvent cycle collection
NS_IMPL_CYCLE_COLLECTION_CLASS(AccEvent) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(AccEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(AccEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)

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

@ -56,7 +56,7 @@ NotificationController::~NotificationController()
NS_IMPL_ADDREF(NotificationController) NS_IMPL_ADDREF(NotificationController)
NS_IMPL_RELEASE(NotificationController) NS_IMPL_RELEASE(NotificationController)
NS_IMPL_CYCLE_COLLECTION_CLASS(NotificationController) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController)
if (tmp->mDocument) if (tmp->mDocument)
@ -812,7 +812,7 @@ NotificationController::ContentInsertion::
return haveToUpdate; return haveToUpdate;
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(NotificationController::ContentInsertion) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController::ContentInsertion)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController::ContentInsertion) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController::ContentInsertion)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContainer) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContainer)

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

@ -111,7 +111,7 @@ Accessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
*aInstancePtr = nsnull; *aInstancePtr = nsnull;
if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
*aInstancePtr = &NS_CYCLE_COLLECTION_NAME(Accessible); *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(Accessible);
return NS_OK; return NS_OK;
} }

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

@ -2158,7 +2158,7 @@ typedef nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
#define NS_HOLD_JS_OBJECTS(obj, clazz) \ #define NS_HOLD_JS_OBJECTS(obj, clazz) \
nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \ nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \
&NS_CYCLE_COLLECTION_NAME(clazz)) NS_CYCLE_COLLECTION_PARTICIPANT(clazz))
#define NS_DROP_JS_OBJECTS(obj, clazz) \ #define NS_DROP_JS_OBJECTS(obj, clazz) \
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz)) nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))

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

@ -130,7 +130,7 @@ nsNodeInfoManager::~nsNodeInfoManager()
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsNodeInfoManager, Release) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsNodeInfoManager, Release)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager)

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

@ -145,7 +145,7 @@ nsEventListenerManager::Shutdown()
nsDOMEvent::Shutdown(); nsDOMEvent::Shutdown();
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsEventListenerManager) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsEventListenerManager, AddRef) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsEventListenerManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsEventListenerManager, Release) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsEventListenerManager, Release)

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

@ -257,7 +257,7 @@ TraverseKey(nsISupports* aKey, nsInsertionPointList* aData, void* aClosure)
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding)
// XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because // XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because
// mPrototypeBinding is weak. // mPrototypeBinding is weak.

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

@ -24,7 +24,7 @@ nsXBLInsertionPoint::~nsXBLInsertionPoint()
} }
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate)

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

@ -227,7 +227,7 @@ private:
PRUint32 nsXBLInsertionPointEntry::gRefCnt = 0; PRUint32 nsXBLInsertionPointEntry::gRefCnt = 0;
nsFixedSizeAllocator* nsXBLInsertionPointEntry::kPool; nsFixedSizeAllocator* nsXBLInsertionPointEntry::kPool;
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPointEntry) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPointEntry)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPointEntry) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPointEntry)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInsertionParent) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInsertionParent)
if (tmp->mDefaultContent) { if (tmp->mDefaultContent) {

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

@ -755,7 +755,7 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
if (!elem->mHoldsScriptObject) { if (!elem->mHoldsScriptObject) {
rv = nsContentUtils::HoldJSObjects( rv = nsContentUtils::HoldJSObjects(
elem, &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode)); elem, NS_CYCLE_COLLECTION_PARTICIPANT(nsXULPrototypeNode));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
@ -3098,7 +3098,7 @@ nsXULPrototypeScript::Set(JSScript* aObject)
} }
nsresult rv = nsContentUtils::HoldJSObjects( nsresult rv = nsContentUtils::HoldJSObjects(
this, &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode)); this, NS_CYCLE_COLLECTION_PARTICIPANT(nsXULPrototypeNode));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mScriptObject.mObject = aObject; mScriptObject.mObject = aObject;
} }

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

@ -10,7 +10,7 @@
NS_IMPL_ADDREF(nsXMLBindingSet) NS_IMPL_ADDREF(nsXMLBindingSet)
NS_IMPL_RELEASE(nsXMLBindingSet) NS_IMPL_RELEASE(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLBindingSet) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXMLBindingSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXMLBindingSet) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXMLBindingSet)
nsXMLBinding* binding = tmp->mFirst; nsXMLBinding* binding = tmp->mFirst;

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

@ -85,7 +85,7 @@ TraverseRuleToBindingsMap(nsISupports* aKey, nsXMLBindingSet* aMatch, void* aCon
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap key"); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap key");
cb->NoteXPCOMChild(aKey); cb->NoteXPCOMChild(aKey);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap value"); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mRuleToBindingsMap value");
cb->NoteNativeChild(aMatch, &NS_CYCLE_COLLECTION_NAME(nsXMLBindingSet)); cb->NoteNativeChild(aMatch, NS_CYCLE_COLLECTION_PARTICIPANT(nsXMLBindingSet));
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
} }

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

@ -538,7 +538,7 @@ nsTimeout::~nsTimeout()
MOZ_COUNT_DTOR(nsTimeout); MOZ_COUNT_DTOR(nsTimeout);
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsTimeout) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsTimeout) NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsTimeout) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsTimeout)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow,
@ -1225,7 +1225,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalWindow)
for (nsTimeout* timeout = tmp->FirstTimeout(); for (nsTimeout* timeout = tmp->FirstTimeout();
tmp->IsTimeout(timeout); tmp->IsTimeout(timeout);
timeout = timeout->Next()) { timeout = timeout->Next()) {
cb.NoteNativeChild(timeout, &NS_CYCLE_COLLECTION_NAME(nsTimeout)); cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLocalStorage) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLocalStorage)

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

@ -43,7 +43,7 @@ nsTransactionItem::Release() {
return mRefCnt; return mRefCnt;
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsTransactionItem) NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsTransactionItem)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsTransactionItem) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsTransactionItem)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)

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

@ -95,7 +95,7 @@ nsTransactionStack::DoTraverse(nsCycleCollectionTraversalCallback &cb)
static_cast<nsTransactionItem*>(mQue.ObjectAt(i)); static_cast<nsTransactionItem*>(mQue.ObjectAt(i));
if (item) { if (item) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "transaction stack mQue[i]"); NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "transaction stack mQue[i]");
cb.NoteNativeChild(item, &NS_CYCLE_COLLECTION_NAME(nsTransactionItem)); cb.NoteNativeChild(item, NS_CYCLE_COLLECTION_PARTICIPANT(nsTransactionItem));
} }
} }
} }

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

@ -17,8 +17,9 @@
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXPCWrappedJS) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXPCWrappedJS)
NS_IMETHODIMP NS_IMETHODIMP
NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::TraverseImpl
(void *p, nsCycleCollectionTraversalCallback &cb) (NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS) *that, void *p,
nsCycleCollectionTraversalCallback &cb)
{ {
nsISupports *s = static_cast<nsISupports*>(p); nsISupports *s = static_cast<nsISupports*>(p);
NS_ASSERTION(CheckForRightISupports(s), NS_ASSERTION(CheckForRightISupports(s),
@ -98,7 +99,7 @@ nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr)
} }
if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) {
*aInstancePtr = & NS_CYCLE_COLLECTION_NAME(nsXPCWrappedJS); *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(nsXPCWrappedJS);
return NS_OK; return NS_OK;
} }

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

@ -44,7 +44,7 @@ xpc_OkToHandOutWrapper(nsWrapperCache *cache)
NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative)
NS_IMETHODIMP NS_IMETHODIMP
NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Unlink(void *p) NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::UnlinkImpl(void *p)
{ {
XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p); XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);
tmp->ExpireWrapper(); tmp->ExpireWrapper();
@ -52,8 +52,9 @@ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Unlink(void *p)
} }
NS_IMETHODIMP NS_IMETHODIMP
NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Traverse(void *p, NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::TraverseImpl
nsCycleCollectionTraversalCallback &cb) (NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative) *that, void *p,
nsCycleCollectionTraversalCallback &cb)
{ {
XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p); XPCWrappedNative *tmp = static_cast<XPCWrappedNative*>(p);
if (!tmp->IsValid()) if (!tmp->IsValid())

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

@ -543,28 +543,33 @@ nsXPConnect::FinishTraverse()
return NS_OK; return NS_OK;
} }
class nsXPConnectParticipant: public nsCycleCollectionParticipant
{
public:
static NS_METHOD RootImpl(void *n)
{
return NS_OK;
}
static NS_METHOD UnlinkImpl(void *n)
{
return NS_OK;
}
static NS_METHOD UnrootImpl(void *n)
{
return NS_OK;
}
static NS_METHOD TraverseImpl(nsXPConnectParticipant *that, void *n,
nsCycleCollectionTraversalCallback &cb);
};
static CCParticipantVTable<nsXPConnectParticipant>::Type XPConnect_cycleCollectorGlobal = {
NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(nsXPConnectParticipant)
};
nsCycleCollectionParticipant * nsCycleCollectionParticipant *
nsXPConnect::GetParticipant() nsXPConnect::GetParticipant()
{ {
return this; return XPConnect_cycleCollectorGlobal.GetParticipant();
}
NS_IMETHODIMP
nsXPConnect::Root(void *p)
{
return NS_OK;
}
NS_IMETHODIMP
nsXPConnect::Unlink(void *p)
{
return NS_OK;
}
NS_IMETHODIMP
nsXPConnect::Unroot(void *p)
{
return NS_OK;
} }
JSBool JSBool
@ -756,8 +761,9 @@ WrapperIsNotMainThreadOnly(XPCWrappedNative *wrapper)
return NS_FAILED(CallQueryInterface(wrapper->Native(), &participant)); return NS_FAILED(CallQueryInterface(wrapper->Native(), &participant));
} }
NS_IMETHODIMP NS_METHOD
nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) nsXPConnectParticipant::TraverseImpl(nsXPConnectParticipant *that, void *p,
nsCycleCollectionTraversalCallback &cb)
{ {
JSGCTraceKind traceKind = js_GetGCThingTraceKind(p); JSGCTraceKind traceKind = js_GetGCThingTraceKind(p);
JSObject *obj = nsnull; JSObject *obj = nsnull;
@ -843,7 +849,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
TraversalTracer trc(cb); TraversalTracer trc(cb);
JS_TracerInit(&trc, GetRuntime()->GetJSRuntime(), NoteJSChild); JS_TracerInit(&trc, nsXPConnect::GetRuntimeInstance()->GetJSRuntime(), NoteJSChild);
trc.eagerlyTraceWeakMaps = false; trc.eagerlyTraceWeakMaps = false;
JS_TraceChildren(&trc, p, traceKind); JS_TraceChildren(&trc, p, traceKind);
@ -897,11 +903,11 @@ nsXPConnect::GetOutstandingRequests(JSContext* cx)
class JSContextParticipant : public nsCycleCollectionParticipant class JSContextParticipant : public nsCycleCollectionParticipant
{ {
public: public:
NS_IMETHOD Root(void *n) static NS_METHOD RootImpl(void *n)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHOD Unlink(void *n) static NS_METHOD UnlinkImpl(void *n)
{ {
JSContext *cx = static_cast<JSContext*>(n); JSContext *cx = static_cast<JSContext*>(n);
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
@ -909,11 +915,12 @@ public:
JS_SetGlobalObject(cx, NULL); JS_SetGlobalObject(cx, NULL);
return NS_OK; return NS_OK;
} }
NS_IMETHOD Unroot(void *n) static NS_METHOD UnrootImpl(void *n)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP Traverse(void *n, nsCycleCollectionTraversalCallback &cb) static NS_METHOD TraverseImpl(JSContextParticipant *that, void *n,
nsCycleCollectionTraversalCallback &cb)
{ {
JSContext *cx = static_cast<JSContext*>(n); JSContext *cx = static_cast<JSContext*>(n);
@ -932,20 +939,22 @@ public:
} }
}; };
static JSContextParticipant JSContext_cycleCollectorGlobal; static CCParticipantVTable<JSContextParticipant>::Type JSContext_cycleCollectorGlobal = {
NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(JSContextParticipant)
};
// static // static
nsCycleCollectionParticipant* nsCycleCollectionParticipant*
nsXPConnect::JSContextParticipant() nsXPConnect::JSContextParticipant()
{ {
return &JSContext_cycleCollectorGlobal; return JSContext_cycleCollectorGlobal.GetParticipant();
} }
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
nsXPConnect::NoteJSContext(JSContext *aJSContext, nsXPConnect::NoteJSContext(JSContext *aJSContext,
nsCycleCollectionTraversalCallback &aCb) nsCycleCollectionTraversalCallback &aCb)
{ {
aCb.NoteNativeChild(aJSContext, &JSContext_cycleCollectorGlobal); aCb.NoteNativeChild(aJSContext, JSContext_cycleCollectorGlobal.GetParticipant());
} }

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

@ -478,7 +478,6 @@ class nsXPConnect : public nsIXPConnect,
public nsIThreadObserver, public nsIThreadObserver,
public nsSupportsWeakReference, public nsSupportsWeakReference,
public nsCycleCollectionJSRuntime, public nsCycleCollectionJSRuntime,
public nsCycleCollectionParticipant,
public nsIJSRuntimeService, public nsIJSRuntimeService,
public nsIThreadJSContextStack, public nsIThreadJSContextStack,
public nsIJSEngineTelemetryStats public nsIJSEngineTelemetryStats
@ -539,13 +538,6 @@ public:
nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info); nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info); nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
// nsCycleCollectionParticipant
NS_IMETHOD Root(void *p);
NS_IMETHOD Unlink(void *p);
NS_IMETHOD Unroot(void *p);
NS_IMETHOD Traverse(void *p,
nsCycleCollectionTraversalCallback &cb);
// nsCycleCollectionLanguageRuntime // nsCycleCollectionLanguageRuntime
virtual bool NotifyLeaveMainThread(); virtual bool NotifyLeaveMainThread();
virtual void NotifyEnterCycleCollectionThread(); virtual void NotifyEnterCycleCollectionThread();
@ -2555,9 +2547,9 @@ public:
{ {
NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(XPCWrappedNative, NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(XPCWrappedNative,
XPCWrappedNative) XPCWrappedNative)
NS_IMETHOD Root(void *p) { return NS_OK; } static NS_METHOD RootImpl(void *p) { return NS_OK; }
NS_IMETHOD Unlink(void *p); static NS_METHOD UnlinkImpl(void *p);
NS_IMETHOD Unroot(void *p) { return NS_OK; } static NS_METHOD UnrootImpl(void *p) { return NS_OK; }
}; };
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative) NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative)

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

@ -72,10 +72,11 @@ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
public: \ public: \
NS_IMETHOD Unlink(void *p); \ static NS_METHOD UnlinkImpl(void *p); \
NS_IMETHOD Traverse(void *p, \ static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_INNERCLASS *that, \
nsCycleCollectionTraversalCallback &cb); \ void *p, \
NS_IMETHOD_(void) UnmarkIfPurple(nsISupports *p) \ nsCycleCollectionTraversalCallback &cb); \
static NS_METHOD_(void) UnmarkIfPurpleImpl(nsISupports *p) \
{ \ { \
Downcast(p)->UnmarkIfPurple(); \ Downcast(p)->UnmarkIfPurple(); \
} \ } \
@ -263,14 +264,14 @@ _class::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr) \
if (aIID.Equals(IsPartOfAggregated() ? \ if (aIID.Equals(IsPartOfAggregated() ? \
NS_GET_IID(nsCycleCollectionParticipant) : \ NS_GET_IID(nsCycleCollectionParticipant) : \
NS_GET_IID(nsAggregatedCycleCollectionParticipant))) \ NS_GET_IID(nsAggregatedCycleCollectionParticipant))) \
foundInterface = & NS_CYCLE_COLLECTION_NAME(_class); \ foundInterface = NS_CYCLE_COLLECTION_PARTICIPANT(_class); \
else else
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraverseImpl \
(void *p, \ (NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, \
nsCycleCollectionTraversalCallback &cb) \ void *p, nsCycleCollectionTraversalCallback &cb) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \

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

@ -6,8 +6,9 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
static void void
NoteChild(void *aScriptThing, const char *name, void *aClosure) nsScriptObjectTracer::NoteJSChild(void *aScriptThing, const char *name,
void *aClosure)
{ {
nsCycleCollectionTraversalCallback *cb = nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(aClosure); static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
@ -15,15 +16,8 @@ NoteChild(void *aScriptThing, const char *name, void *aClosure)
cb->NoteJSChild(aScriptThing); cb->NoteJSChild(aScriptThing);
} }
void
nsScriptObjectTracer::TraverseScriptObjects(void *p,
nsCycleCollectionTraversalCallback &cb)
{
Trace(p, NoteChild, &cb);
}
nsresult nsresult
nsXPCOMCycleCollectionParticipant::Root(void *p) nsXPCOMCycleCollectionParticipant::RootImpl(void *p)
{ {
nsISupports *s = static_cast<nsISupports*>(p); nsISupports *s = static_cast<nsISupports*>(p);
NS_ADDREF(s); NS_ADDREF(s);
@ -31,13 +25,13 @@ nsXPCOMCycleCollectionParticipant::Root(void *p)
} }
nsresult nsresult
nsXPCOMCycleCollectionParticipant::Unlink(void *p) nsXPCOMCycleCollectionParticipant::UnlinkImpl(void *p)
{ {
return NS_OK; return NS_OK;
} }
nsresult nsresult
nsXPCOMCycleCollectionParticipant::Unroot(void *p) nsXPCOMCycleCollectionParticipant::UnrootImpl(void *p)
{ {
nsISupports *s = static_cast<nsISupports*>(p); nsISupports *s = static_cast<nsISupports*>(p);
NS_RELEASE(s); NS_RELEASE(s);
@ -45,20 +39,21 @@ nsXPCOMCycleCollectionParticipant::Unroot(void *p)
} }
nsresult nsresult
nsXPCOMCycleCollectionParticipant::Traverse nsXPCOMCycleCollectionParticipant::TraverseImpl
(void *p, nsCycleCollectionTraversalCallback &cb) (nsXPCOMCycleCollectionParticipant* that, void *p,
nsCycleCollectionTraversalCallback &cb)
{ {
return NS_OK; return NS_OK;
} }
void void
nsXPCOMCycleCollectionParticipant::UnmarkIfPurple(nsISupports *n) nsXPCOMCycleCollectionParticipant::UnmarkIfPurpleImpl(nsISupports *n)
{ {
} }
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
nsXPCOMCycleCollectionParticipant::Trace(void *p, TraceCallback cb, nsXPCOMCycleCollectionParticipant::TraceImpl(void *p, TraceCallback cb,
void *closure) void *closure)
{ {
} }

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

@ -6,6 +6,7 @@
#ifndef nsCycleCollectionParticipant_h__ #ifndef nsCycleCollectionParticipant_h__
#define nsCycleCollectionParticipant_h__ #define nsCycleCollectionParticipant_h__
#include "mozilla/TypeTraits.h"
#include "nsISupports.h" #include "nsISupports.h"
#define NS_CYCLECOLLECTIONPARTICIPANT_IID \ #define NS_CYCLECOLLECTIONPARTICIPANT_IID \
@ -43,7 +44,18 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports, NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports,
NS_CYCLECOLLECTIONISUPPORTS_IID) NS_CYCLECOLLECTIONISUPPORTS_IID)
/**
* Forward declarations
*/
class nsCycleCollectionParticipant; class nsCycleCollectionParticipant;
class nsScriptObjectTracer;
class nsXPCOMCycleCollectionParticipant;
/**
* Callback definitions
*/
typedef void
(* TraceCallback)(void *p, const char *name, void *closure);
class NS_NO_VTABLE nsCycleCollectionTraversalCallback class NS_NO_VTABLE nsCycleCollectionTraversalCallback
{ {
@ -97,27 +109,162 @@ protected:
PRUint32 mFlags; PRUint32 mFlags;
}; };
class NS_NO_VTABLE nsCycleCollectionParticipant /**
* VTables
*
* When using global scope static initialization for simple types with virtual
* member functions, GCC creates static initializer functions. In order to
* avoid this from happening, cycle collection participants are defined as
* function tables.
*
* The Traverse function may require calling another function from the cycle
* collection participant function table, so a pointer to the function table
* is given to it. Using member function pointers would be less awkward, but
* in MSVC, the size of such a member function pointer depends on the class
* the function is member of. This makes it hard to make them compatible with
* a generic function table. Moreover, static initialization of the function
* table then uses a static initializer function.
*
* Finally, it is not possible to use an initializer list for non-aggregate
* types. Separate types are thus required for static initialization. For
* convenience and to avoid repetitions that could lead to discrepancies,
* function table members for sub-types are declared independently, and
* different aggregate types are defined for static initialization.
*/
/* Base functions for nsCycleCollectionParticipant */
template <typename T>
struct nsCycleCollectionParticipantVTableCommon
{
nsresult (NS_STDCALL *TraverseReal)
(T *that, void *p, nsCycleCollectionTraversalCallback &cb);
nsresult (NS_STDCALL *Root)(void *p);
nsresult (NS_STDCALL *Unlink)(void *p);
nsresult (NS_STDCALL *Unroot)(void *p);
bool (NS_STDCALL *CanSkipReal)(void *p, bool aRemovingAllowed);
bool (NS_STDCALL *CanSkipInCCReal)(void *p);
bool (NS_STDCALL *CanSkipThisReal)(void *p);
};
typedef nsCycleCollectionParticipantVTableCommon<nsCycleCollectionParticipant>
nsCycleCollectionParticipantVTable;
/* Additional functions for nsScriptObjectTracer */
struct nsScriptObjectTracerVTable
{
void (NS_STDCALL *Trace)(void *p, TraceCallback cb, void *closure);
};
/* Additional functions for nsXPCOMCycleCollectionParticipant */
struct nsXPCOMCycleCollectionParticipantVTable
{
void (NS_STDCALL *UnmarkIfPurple)(nsISupports *p);
};
/**
* Types for static initialization
*
* Considering T, the cycle collection participant class, subclass of either
* nsCycleCollectionParticipant, nsScriptObjectTracer or
* nsXPCOMCycleCollectionParticipant, static initialization goes as follows:
*
* CCParticipantVTable<T>::type T::_cycleCollectorGlobal = {{...} ...};
*
* CCParticipantVTable<T>::type automatically defines the right type considering
* what particular cycle collection participant class T derives from.
*
* The NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(classname),
* NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(classname), and
* NS_IMPL_CYCLE_COLLECTION_VTABLE(classname) macros may be used as helpers
* for static initialization:
*
* CCParticipantVTable<T>::type T::_cycleCollectorGlobal = {
* NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(classname);
* };
*/
enum nsCycleCollectionParticipantType
{
eInvalid,
eCycleCollectionParticipant,
eScriptObjectTracer,
eXPCOMCycleCollectionParticipant
};
template <typename T, enum nsCycleCollectionParticipantType ParticipantType>
struct CCParticipantVTableImpl { };
/* CCParticipantVTable for nsCycleCollectionParticipant */
template <typename T>
struct CCParticipantVTableImpl<T, eCycleCollectionParticipant>
{
nsCycleCollectionParticipant *GetParticipant()
{
return reinterpret_cast<nsCycleCollectionParticipant *>(this);
}
nsCycleCollectionParticipantVTableCommon<T> cycleCollectionParticipant;
};
/* CCParticipantVTable for nsScriptObjectTracer */
template <typename T>
struct CCParticipantVTableImpl<T, eScriptObjectTracer>
{
nsScriptObjectTracer *GetParticipant()
{
return reinterpret_cast<nsScriptObjectTracer *>(this);
}
nsCycleCollectionParticipantVTableCommon<T> cycleCollectionParticipant;
nsScriptObjectTracerVTable scriptObjectTracer;
};
/* CCParticipantVTable for nsXPCOMCycleCollectionParticipant */
template <typename T>
struct CCParticipantVTableImpl<T, eXPCOMCycleCollectionParticipant>
{
nsXPCOMCycleCollectionParticipant *GetParticipant()
{
return reinterpret_cast<nsXPCOMCycleCollectionParticipant *>(this);
}
nsCycleCollectionParticipantVTableCommon<T> cycleCollectionParticipant;
nsScriptObjectTracerVTable scriptObjectTracer;
nsXPCOMCycleCollectionParticipantVTable XPCOMCycleCollectionParticipant;
};
template <typename T>
struct CCParticipantVTable
{
static const enum nsCycleCollectionParticipantType ParticipantType =
mozilla::IsBaseOf<nsXPCOMCycleCollectionParticipant, T>::value ? eXPCOMCycleCollectionParticipant :
mozilla::IsBaseOf<nsScriptObjectTracer, T>::value ? eScriptObjectTracer :
mozilla::IsBaseOf<nsCycleCollectionParticipant, T>::value ? eCycleCollectionParticipant :
eInvalid;
typedef CCParticipantVTableImpl<T, ParticipantType> Type;
};
/**
* Participant implementation classes
*/
class nsCycleCollectionParticipant : public nsCycleCollectionParticipantVTable
{ {
public: public:
nsCycleCollectionParticipant() : mMightSkip(false) {} static const bool isSkippable = false;
nsCycleCollectionParticipant(bool aSkip) : mMightSkip(aSkip) {}
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0; // Helper function to avoid painful syntax for member function call using
// the VTable entry.
NS_IMETHOD Root(void *p) = 0; NS_METHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) {
NS_IMETHOD Unlink(void *p) = 0; return TraverseReal(this, p, cb);
NS_IMETHOD Unroot(void *p) = 0; }
// If CanSkip returns true, p is removed from the purple buffer during // If CanSkip returns true, p is removed from the purple buffer during
// a call to nsCycleCollector_forgetSkippable(). // a call to nsCycleCollector_forgetSkippable().
// Note, calling CanSkip may remove objects from the purple buffer! // Note, calling CanSkip may remove objects from the purple buffer!
// If aRemovingAllowed is true, p can be removed from the purple buffer. // If aRemovingAllowed is true, p can be removed from the purple buffer.
bool CanSkip(void *p, bool aRemovingAllowed) bool CanSkip(void *p, bool aRemovingAllowed)
{ {
return mMightSkip ? CanSkipReal(p, aRemovingAllowed) : false; return CanSkipReal ? CanSkipReal(p, aRemovingAllowed) : false;
} }
// If CanSkipInCC returns true, p is skipped when selecting roots for the // If CanSkipInCC returns true, p is skipped when selecting roots for the
@ -125,7 +272,7 @@ public:
// Note, calling CanSkipInCC may remove other objects from the purple buffer! // Note, calling CanSkipInCC may remove other objects from the purple buffer!
bool CanSkipInCC(void *p) bool CanSkipInCC(void *p)
{ {
return mMightSkip ? CanSkipInCCReal(p) : false; return CanSkipInCCReal ? CanSkipInCCReal(p) : false;
} }
// If CanSkipThis returns true, p is not added to the graph. // If CanSkipThis returns true, p is not added to the graph.
@ -133,73 +280,39 @@ public:
// change the state of any objects! // change the state of any objects!
bool CanSkipThis(void *p) bool CanSkipThis(void *p)
{ {
return mMightSkip ? CanSkipThisReal(p) : false; return CanSkipThisReal ? CanSkipThisReal(p) : false;
} }
protected:
NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed)
{
NS_ASSERTION(false, "Forgot to implement CanSkipReal?");
return false;
}
NS_IMETHOD_(bool) CanSkipInCCReal(void *p)
{
NS_ASSERTION(false, "Forgot to implement CanSkipInCCReal?");
return false;
}
NS_IMETHOD_(bool) CanSkipThisReal(void *p)
{
NS_ASSERTION(false, "Forgot to implement CanSkipThisReal?");
return false;
}
bool mMightSkip;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant, NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
NS_CYCLECOLLECTIONPARTICIPANT_IID) NS_CYCLECOLLECTIONPARTICIPANT_IID)
#undef IMETHOD_VISIBILITY class nsScriptObjectTracer
#define IMETHOD_VISIBILITY NS_COM_GLUE : public nsCycleCollectionParticipant, public nsScriptObjectTracerVTable
typedef void
(* TraceCallback)(void *p, const char *name, void *closure);
class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
{ {
public: public:
nsScriptObjectTracer() : nsCycleCollectionParticipant(false) {} static void NS_COM_GLUE NoteJSChild(void *aScriptThing, const char *name,
nsScriptObjectTracer(bool aSkip) : nsCycleCollectionParticipant(aSkip) {} void *aClosure);
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
void NS_COM_GLUE TraverseScriptObjects(void *p,
nsCycleCollectionTraversalCallback &cb);
}; };
class NS_COM_GLUE nsXPCOMCycleCollectionParticipant class nsXPCOMCycleCollectionParticipant
: public nsScriptObjectTracer : public nsScriptObjectTracer, public nsXPCOMCycleCollectionParticipantVTable
{ {
public: public:
nsXPCOMCycleCollectionParticipant() static NS_METHOD TraverseImpl(nsXPCOMCycleCollectionParticipant *that,
: nsScriptObjectTracer(false) {} void *p, nsCycleCollectionTraversalCallback &cb);
nsXPCOMCycleCollectionParticipant(bool aSkip)
: nsScriptObjectTracer(aSkip) {}
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); static NS_METHOD RootImpl(void *p);
static NS_METHOD UnlinkImpl(void *p);
static NS_METHOD UnrootImpl(void *p);
NS_IMETHOD Root(void *p); static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure);
NS_IMETHOD Unlink(void *p);
NS_IMETHOD Unroot(void *p);
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); static NS_METHOD_(void) UnmarkIfPurpleImpl(nsISupports *p);
NS_IMETHOD_(void) UnmarkIfPurple(nsISupports *p); static bool CheckForRightISupports(nsISupports *s);
bool CheckForRightISupports(nsISupports *s);
}; };
#undef IMETHOD_VISIBILITY
#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant // Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -213,12 +326,12 @@ public:
#define NS_CYCLE_COLLECTION_INNERNAME \ #define NS_CYCLE_COLLECTION_INNERNAME \
_cycleCollectorGlobal _cycleCollectorGlobal
#define NS_CYCLE_COLLECTION_NAME(_class) \ #define NS_CYCLE_COLLECTION_PARTICIPANT(_class) \
_class::NS_CYCLE_COLLECTION_INNERNAME _class::NS_CYCLE_COLLECTION_INNERNAME.GetParticipant()
#define NS_IMPL_QUERY_CYCLE_COLLECTION(_class) \ #define NS_IMPL_QUERY_CYCLE_COLLECTION(_class) \
if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \ if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
*aInstancePtr = & NS_CYCLE_COLLECTION_NAME(_class); \ *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(_class); \
return NS_OK; \ return NS_OK; \
} else } else
@ -257,7 +370,7 @@ public:
NS_PRECONDITION(aInstancePtr, "null out param"); \ NS_PRECONDITION(aInstancePtr, "null out param"); \
\ \
if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \ if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
*aInstancePtr = &NS_CYCLE_COLLECTION_NAME(_class); \ *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(_class); \
return NS_OK; \ return NS_OK; \
} \ } \
nsresult rv; nsresult rv;
@ -270,8 +383,8 @@ public:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(_class) \
NS_IMETHODIMP_(bool) \ NS_METHOD_(bool) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipReal(void *p, \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipImpl(void *p, \
bool aRemovingAllowed) \ bool aRemovingAllowed) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
@ -285,8 +398,8 @@ public:
} }
#define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(_class) \
NS_IMETHODIMP_(bool) \ NS_METHOD_(bool) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipInCCReal(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipInCCImpl(void *p) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
@ -299,8 +412,8 @@ public:
} }
#define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(_class) \
NS_IMETHODIMP_(bool) \ NS_METHOD_(bool) \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipThisReal(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipThisImpl(void *p) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
@ -317,8 +430,8 @@ public:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnlinkImpl(void *p) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
@ -326,18 +439,18 @@ public:
_class *tmp = Downcast(s); _class *tmp = Downcast(s);
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class) \ #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnlinkImpl(void *p) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
"not the nsISupports pointer we expect"); \ "not the nsISupports pointer we expect"); \
_class *tmp = static_cast<_class*>(Downcast(s)); \ _class *tmp = static_cast<_class*>(Downcast(s)); \
NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s); NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::UnlinkImpl(s);
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(_class) \ #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnlinkImpl(void *p) \
{ \ { \
_class *tmp = static_cast<_class*>(p); _class *tmp = static_cast<_class*>(p);
@ -356,8 +469,8 @@ public:
} }
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \ #define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnlinkImpl(void *p) \
{ \ { \
NS_ASSERTION(CheckForRightISupports(static_cast<nsISupports*>(p)), \ NS_ASSERTION(CheckForRightISupports(static_cast<nsISupports*>(p)), \
"not the nsISupports pointer we expect"); \ "not the nsISupports pointer we expect"); \
@ -365,8 +478,8 @@ public:
} }
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(_class) \ #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnlinkImpl(void *p) \
{ \ { \
return NS_OK; \ return NS_OK; \
} }
@ -380,9 +493,9 @@ public:
cb.DescribeRefCountedNode(_refcnt, sizeof(_class), #_class); cb.DescribeRefCountedNode(_refcnt, sizeof(_class), #_class);
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraverseImpl \
(void *p, \ (NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, void *p,\
nsCycleCollectionTraversalCallback &cb) \ nsCycleCollectionTraversalCallback &cb) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
@ -402,15 +515,15 @@ public:
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \
if (NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Traverse(s, cb) == \ if (NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::TraverseImpl(that, s, cb) \
NS_SUCCESS_INTERRUPTED_TRAVERSE) { \ == NS_SUCCESS_INTERRUPTED_TRAVERSE) { \
return NS_SUCCESS_INTERRUPTED_TRAVERSE; \ return NS_SUCCESS_INTERRUPTED_TRAVERSE; \
} }
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(_class) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraverseImpl \
(void *p, \ (NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, void *p,\
nsCycleCollectionTraversalCallback &cb) \ nsCycleCollectionTraversalCallback &cb) \
{ \ { \
_class *tmp = static_cast<_class*>(p); \ _class *tmp = static_cast<_class*>(p); \
@ -453,7 +566,7 @@ public:
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(_ptr, _ptr_class, _name) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(_ptr, _ptr_class, _name) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, _name); \ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, _name); \
cb.NoteNativeChild(_ptr, &NS_CYCLE_COLLECTION_NAME(_ptr_class)); \ cb.NoteNativeChild(_ptr, NS_CYCLE_COLLECTION_PARTICIPANT(_ptr_class)); \
PR_END_MACRO; PR_END_MACRO;
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(_field, _field_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(_field, _field_class) \
@ -485,7 +598,7 @@ public:
#_field) #_field)
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
TraverseScriptObjects(p, cb); that->Trace(p, &nsScriptObjectTracer::NoteJSChild, &cb);
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
return NS_OK; \ return NS_OK; \
@ -497,9 +610,9 @@ public:
#define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \
void \ void \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraceImpl(void *p, \
TraceCallback aCallback, \ TraceCallback aCallback, \
void *aClosure) \ void *aClosure) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
@ -508,23 +621,23 @@ public:
#define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(_class, _base_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(_class, _base_class) \
void \ void \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraceImpl(void *p, \
TraceCallback aCallback, \ TraceCallback aCallback, \
void *aClosure) \ void *aClosure) \
{ \ { \
nsISupports *s = static_cast<nsISupports*>(p); \ nsISupports *s = static_cast<nsISupports*>(p); \
NS_ASSERTION(CheckForRightISupports(s), \ NS_ASSERTION(CheckForRightISupports(s), \
"not the nsISupports pointer we expect"); \ "not the nsISupports pointer we expect"); \
_class *tmp = static_cast<_class*>(Downcast(s)); \ _class *tmp = static_cast<_class*>(Downcast(s)); \
NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Trace(s, \ NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::TraceImpl(s, \
aCallback, \ aCallback, \
aClosure); aClosure);
#define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class) \ #define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class) \
void \ void \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraceImpl(void *p, \
TraceCallback aCallback, \ TraceCallback aCallback, \
void *aClosure) \ void *aClosure) \
{ \ { \
_class *tmp = static_cast<_class*>(p); _class *tmp = static_cast<_class*>(p);
@ -553,13 +666,14 @@ public:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE \ #define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; static CCParticipantVTable<NS_CYCLE_COLLECTION_INNERCLASS>::Type \
NS_CYCLE_COLLECTION_INNERNAME;
#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
public: \ public: \
NS_IMETHOD Traverse(void *p, \ static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, \
nsCycleCollectionTraversalCallback &cb); \ void *p, nsCycleCollectionTraversalCallback &cb); \
NS_IMETHOD_(void) UnmarkIfPurple(nsISupports *s) \ static NS_METHOD_(void) UnmarkIfPurpleImpl(nsISupports *s) \
{ \ { \
Downcast(s)->UnmarkIfPurple(); \ Downcast(s)->UnmarkIfPurple(); \
} \ } \
@ -574,7 +688,7 @@ public: \
#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \ NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
NS_IMETHOD Unlink(void *p); static NS_METHOD UnlinkImpl(void *p);
#define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base) \
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
@ -592,13 +706,11 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
public: \
NS_CYCLE_COLLECTION_INNERCLASS () : nsXPCOMCycleCollectionParticipant(true) {} \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \ NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
protected: \ static const bool isSkippable = true; \
NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \ static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed); \
NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \ static NS_METHOD_(bool) CanSkipInCCImpl(void *p); \
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ static NS_METHOD_(bool) CanSkipThisImpl(void *p); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -613,15 +725,15 @@ 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 Root(void *p) \ static NS_METHOD RootImpl(void *p) \
{ \ { \
return NS_OK; \ return NS_OK; \
} \ } \
NS_IMETHOD Unlink(void *p) \ static NS_METHOD UnlinkImpl(void *p) \
{ \ { \
return NS_OK; \ return NS_OK; \
} \ } \
NS_IMETHOD Unroot(void *p) \ static NS_METHOD UnrootImpl(void *p) \
{ \ { \
return NS_OK; \ return NS_OK; \
} \ } \
@ -633,7 +745,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
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); \ static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -641,14 +753,12 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsXPCOMCycleCollectionParticipant \ : public nsXPCOMCycleCollectionParticipant \
{ \ { \
public: \
NS_CYCLE_COLLECTION_INNERCLASS () : nsXPCOMCycleCollectionParticipant(true) {} \
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); \ static const bool isSkippable = true; \
protected: \ static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \ static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed); \
NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \ static NS_METHOD_(bool) CanSkipInCCImpl(void *p); \
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ static NS_METHOD_(bool) CanSkipThisImpl(void *p); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -660,18 +770,12 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \ : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
{ \ { \
public: \
NS_CYCLE_COLLECTION_INNERCLASS () \
: NS_CYCLE_COLLECTION_CLASSNAME(_base_class)() \
{ \
mMightSkip = true; \
} \
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
protected: \ static const bool isSkippable = true; \
NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \ static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \ static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed); \
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \ static NS_METHOD_(bool) CanSkipInCCImpl(void *p); \
static NS_METHOD_(bool) CanSkipThisImpl(void *p); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -681,8 +785,8 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, \ #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, \
_base_class) \ _base_class) \
public: \ public: \
NS_IMETHOD Traverse(void *p, \ static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, \
nsCycleCollectionTraversalCallback &cb); \ void *p, nsCycleCollectionTraversalCallback &cb); \
static _class* Downcast(nsISupports* s) \ static _class* Downcast(nsISupports* s) \
{ \ { \
return static_cast<_class*>(static_cast<_base_class*>( \ return static_cast<_class*>(static_cast<_base_class*>( \
@ -691,7 +795,7 @@ public: \
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
NS_IMETHOD Unlink(void *p); static NS_METHOD UnlinkImpl(void *p);
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class) \ #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
@ -717,9 +821,8 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \ : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
{ \ { \
public: \
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, void *closure); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -734,22 +837,75 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
{ \ { \
} \ } \
#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \ /**
NS_CYCLE_COLLECTION_CLASSNAME(_class) NS_CYCLE_COLLECTION_NAME(_class); * Dummy class with a definition for CanSkip* function members, but no
* implementation.
*/
struct SkippableDummy
{
static NS_METHOD_(bool) CanSkipImpl(void *p, bool aRemovingAllowed);
static NS_METHOD_(bool) CanSkipInCCImpl(void *p);
static NS_METHOD_(bool) CanSkipThisImpl(void *p);
};
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \ /**
* Skippable<T> defines a class that always has definitions for CanSkip*
* function members, so that T::isSkippable ? &Skippable<T>::CanSkip* : NULL
* can compile when T::isSkippable is false and T doesn't have CanSkip*
* definitions (which, as not being skippable, it's not supposed to have).
*/
template <class T>
struct Skippable
: public mozilla::Conditional<T::isSkippable, T, SkippableDummy>::Type
{ };
#define NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(_class) \
{ \
&_class::TraverseImpl, \
&_class::RootImpl, \
&_class::UnlinkImpl, \
&_class::UnrootImpl, \
_class::isSkippable ? &Skippable<_class>::CanSkipImpl : NULL, \
_class::isSkippable ? &Skippable<_class>::CanSkipInCCImpl : NULL, \
_class::isSkippable ? &Skippable<_class>::CanSkipThisImpl : NULL \
}
#define NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(_class) \
NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(_class), \
{ &_class::TraceImpl }
#define NS_IMPL_CYCLE_COLLECTION_VTABLE(_class) \
NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(_class), \
{ &_class::UnmarkIfPurpleImpl }
#define NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
{ NS_IMPL_CYCLE_COLLECTION_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
#define NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class) \
CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
{ NS_IMPL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
#define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
CCParticipantVTable<NS_CYCLE_COLLECTION_CLASSNAME(_class)> \
::Type _class::NS_CYCLE_COLLECTION_INNERNAME = \
{ NS_IMPL_CYCLE_COLLECTION_VTABLE(NS_CYCLE_COLLECTION_CLASSNAME(_class)) };
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
public: \ public: \
NS_IMETHOD Root(void *n); \ static NS_METHOD RootImpl(void *n); \
NS_IMETHOD Unlink(void *n); \ static NS_METHOD UnlinkImpl(void *n); \
NS_IMETHOD Unroot(void *n); \ static NS_METHOD UnrootImpl(void *n); \
NS_IMETHOD Traverse(void *n, \ static NS_METHOD TraverseImpl(NS_CYCLE_COLLECTION_CLASSNAME(_class) *that, \
nsCycleCollectionTraversalCallback &cb); void *n, nsCycleCollectionTraversalCallback &cb);
#define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \ #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsCycleCollectionParticipant \ : public nsCycleCollectionParticipant \
{ \ { \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \ NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
@ -757,14 +913,15 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
class NS_CYCLE_COLLECTION_INNERCLASS \ class NS_CYCLE_COLLECTION_INNERCLASS \
: public nsScriptObjectTracer \ : public nsScriptObjectTracer \
{ \ { \
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \ NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class) \
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \ static NS_METHOD_(void) TraceImpl(void *p, TraceCallback cb, \
void *closure); \
}; \ }; \
NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE 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_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootImpl(void *p) \
{ \ { \
_class *tmp = static_cast<_class*>(p); \ _class *tmp = static_cast<_class*>(p); \
tmp->_root_function(); \ tmp->_root_function(); \
@ -772,8 +929,8 @@ NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
} }
#define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function) \ #define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function) \
NS_IMETHODIMP \ NS_METHOD \
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p) \ NS_CYCLE_COLLECTION_CLASSNAME(_class)::UnrootImpl(void *p) \
{ \ { \
_class *tmp = static_cast<_class*>(p); \ _class *tmp = static_cast<_class*>(p); \
tmp->_unroot_function(); \ tmp->_unroot_function(); \