From 89520b7407b6c3c545a3936bb4bdc77860ab0276 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Mon, 2 Dec 2013 13:17:29 -0800 Subject: [PATCH] Bug 942528 - Make XPCWN more of a normal cycle collected class. r=smaug --- js/xpconnect/src/XPCWrappedNative.cpp | 18 +++++++++++++++--- js/xpconnect/src/xpcprivate.h | 22 ++-------------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 7d9dcfadbb8d..b88aee46839b 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -41,6 +41,10 @@ xpc_OkToHandOutWrapper(nsWrapperCache *cache) NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) +// No need to unlink the JS objects: if the XPCWrappedNative is cycle +// collected then its mFlatJSObject will be cycle collected too and +// finalization of the mFlatJSObject will unlink the JS objects (see +// XPC_WN_NoHelper_Finalize and FlatJSObjectFinalized). NS_IMETHODIMP_(void) NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Unlink(void *p) { @@ -600,6 +604,8 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed aIdentity, mSet(aProto->GetSet()), mScriptableInfo(nullptr) { + MOZ_ASSERT(NS_IsMainThread()); + mIdentity = aIdentity.get(); mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID); @@ -616,6 +622,8 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed aIdentity, mSet(aSet), mScriptableInfo(nullptr) { + MOZ_ASSERT(NS_IsMainThread()); + mIdentity = aIdentity.get(); mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID); @@ -905,10 +913,14 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCWrappedNative) NS_INTERFACE_MAP_ENTRY(nsIXPConnectWrappedNative) NS_INTERFACE_MAP_ENTRY(nsIXPConnectJSObjectHolder) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPConnectWrappedNative) -NS_INTERFACE_MAP_END_THREADSAFE +NS_INTERFACE_MAP_END -NS_IMPL_ADDREF(XPCWrappedNative) -NS_IMPL_RELEASE(XPCWrappedNative) +NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCWrappedNative) + +// Release calls Destroy() immediately when the refcount drops to 0 to +// clear the weak references nsXPConnect has to XPCWNs and to ensure there +// are no pointers to dying protos. +NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(XPCWrappedNative, Destroy()) /* * Wrapped Native lifetime management is messy! diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 7eaf6be3f237..81fb18097306 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2007,29 +2007,11 @@ TraceXPCGlobal(JSTracer *trc, JSObject *obj); class XPCWrappedNative : public nsIXPConnectWrappedNative { public: - NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIXPCONNECTJSOBJECTHOLDER NS_DECL_NSIXPCONNECTWRAPPEDNATIVE - // No need to unlink the JS objects, if the XPCWrappedNative will be cycle - // collected then its mFlatJSObject will be cycle collected too and - // finalization of the mFlatJSObject will unlink the js objects (see - // XPC_WN_NoHelper_Finalize and FlatJSObjectFinalized). - // We also give XPCWrappedNative empty Root/Unroot methods, to avoid - // root/unrooting the JS objects from addrefing/releasing the - // XPCWrappedNative during unlinking, which would make the JS objects - // uncollectable to the JS GC. - class NS_CYCLE_COLLECTION_INNERCLASS - : public nsXPCOMCycleCollectionParticipant - { - NS_DECL_CYCLE_COLLECTION_CLASS_BODY(XPCWrappedNative, XPCWrappedNative) - 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); - static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; - void DeleteCycleCollectable() {} + NS_DECL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) nsIPrincipal* GetObjectPrincipal() const;