Bug 735280 - Part 1: Connect XPCWrappedNativeScope and Components. r=bholley
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Sat, 28 Apr 2012 09:12:27 -0400
changeset 92661 d7d5e48f6683d4f39bbefc67cd69b960a4260365
parent 92660 cb240b2a69dbd5ffe28bbc6c48e3c9380d0bf367
child 92662 5016ede402601576f96438a1677b7d9d77ab39f5
push id22549
push userryanvm@gmail.com
push dateSun, 29 Apr 2012 20:42:32 +0000
treeherdermozilla-central@32a0e99932b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs735280
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 735280 - Part 1: Connect XPCWrappedNativeScope and Components. r=bholley
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -4240,27 +4240,29 @@ nsXPCComponents::GetFlags(PRUint32 *aFla
 
 /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
 NS_IMETHODIMP
 nsXPCComponents::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
 {
     return NS_ERROR_NOT_AVAILABLE;
 }
 
-nsXPCComponents::nsXPCComponents()
-    :   mInterfaces(nsnull),
+nsXPCComponents::nsXPCComponents(XPCWrappedNativeScope* aScope)
+    :   mScope(aScope),
+        mInterfaces(nsnull),
         mInterfacesByID(nsnull),
         mClasses(nsnull),
         mClassesByID(nsnull),
         mResults(nsnull),
         mID(nsnull),
         mException(nsnull),
         mConstructor(nsnull),
         mUtils(nsnull)
 {
+    MOZ_ASSERT(aScope, "aScope must not be null");
 }
 
 nsXPCComponents::~nsXPCComponents()
 {
     ClearMembers();
 }
 
 void
@@ -4429,17 +4431,17 @@ nsXPCComponents::SetProperty(nsIXPConnec
 JSBool
 nsXPCComponents::AttachNewComponentsObject(XPCCallContext& ccx,
                                            XPCWrappedNativeScope* aScope,
                                            JSObject* aGlobal)
 {
     if (!aGlobal)
         return false;
 
-    nsXPCComponents* components = new nsXPCComponents();
+    nsXPCComponents* components = new nsXPCComponents(aScope);
     if (!components)
         return false;
 
     nsCOMPtr<nsIXPCComponents> cholder(components);
 
     AutoMarkingNativeInterfacePtr iface(ccx);
     iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
 
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -185,21 +185,25 @@ XPCWrappedNativeScope::IsDyingScope(XPCW
             return true;
     }
     return false;
 }
 
 void
 XPCWrappedNativeScope::SetComponents(nsXPCComponents* aComponents)
 {
-    NS_IF_ADDREF(aComponents);
-    NS_IF_RELEASE(mComponents);
     mComponents = aComponents;
 }
 
+nsXPCComponents*
+XPCWrappedNativeScope::GetComponents()
+{
+    return mComponents;
+}
+
 // Dummy JS class to let wrappers w/o an xpc prototype share
 // scopes. By doing this we avoid allocating a new scope for every
 // wrapper on creation of the wrapper, and most wrappers won't need
 // their own scope at all for the lifetime of the wrapper.
 // WRAPPER_SLOTS is key here (even though there's never anything
 // in the private data slot in these prototypes), as the number of
 // reserved slots in this class needs to match that of the wrappers
 // for the JS engine to share scopes.
@@ -303,19 +307,24 @@ XPCWrappedNativeScope::~XPCWrappedNative
     if (mMainThreadWrappedNativeProtoMap) {
         NS_ASSERTION(0 == mMainThreadWrappedNativeProtoMap->Count(), "scope has non-empty map");
         delete mMainThreadWrappedNativeProtoMap;
     }
 
     if (mContext)
         mContext->RemoveScope(this);
 
+    // This should not be necessary, since the Components object should die
+    // with the scope but just in case.
+    if (mComponents)
+        mComponents->mScope = nsnull;
+
     // XXX we should assert that we are dead or that xpconnect has shutdown
     // XXX might not want to do this at xpconnect shutdown time???
-    NS_IF_RELEASE(mComponents);
+    mComponents = nsnull;
 
     JSRuntime *rt = mRuntime->GetJSRuntime();
     mGlobalJSObject.finalize(rt);
     mPrototypeJSObject.finalize(rt);
 }
 
 JSObject *
 XPCWrappedNativeScope::GetPrototypeNoHelper(XPCCallContext& ccx)
@@ -901,17 +910,17 @@ void
 XPCWrappedNativeScope::DebugDump(PRInt16 depth)
 {
 #ifdef DEBUG
     depth-- ;
     XPC_LOG_ALWAYS(("XPCWrappedNativeScope @ %x", this));
     XPC_LOG_INDENT();
         XPC_LOG_ALWAYS(("mRuntime @ %x", mRuntime));
         XPC_LOG_ALWAYS(("mNext @ %x", mNext));
-        XPC_LOG_ALWAYS(("mComponents @ %x", mComponents));
+        XPC_LOG_ALWAYS(("mComponents @ %x", mComponents.get()));
         XPC_LOG_ALWAYS(("mGlobalJSObject @ %x", mGlobalJSObject.get()));
         XPC_LOG_ALWAYS(("mPrototypeJSObject @ %x", mPrototypeJSObject.get()));
         XPC_LOG_ALWAYS(("mPrototypeNoHelper @ %x", mPrototypeNoHelper));
 
         XPC_LOG_ALWAYS(("mWrappedNativeMap @ %x with %d wrappers(s)",         \
                         mWrappedNativeMap,                                    \
                         mWrappedNativeMap ? mWrappedNativeMap->Count() : 0));
         // iterate contexts...
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1587,16 +1587,17 @@ public:
 
     JSBool
     IsValid() const {return mRuntime != nsnull;}
 
     static JSBool
     IsDyingScope(XPCWrappedNativeScope *scope);
 
     void SetComponents(nsXPCComponents* aComponents);
+    nsXPCComponents *GetComponents();
     void SetGlobal(XPCCallContext& ccx, JSObject* aGlobal, nsISupports* aNative);
 
     static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; }
 
     XPCContext *GetContext() { return mContext; }
     void SetContext(XPCContext *xpcc) { mContext = nsnull; }
 
     nsDataHashtable<nsDepCharHashKey, JSObject*>& GetCachedDOMPrototypes()
@@ -1636,17 +1637,17 @@ protected:
 private:
     static XPCWrappedNativeScope* gScopes;
     static XPCWrappedNativeScope* gDyingScopes;
 
     XPCJSRuntime*                    mRuntime;
     Native2WrappedNativeMap*         mWrappedNativeMap;
     ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
     ClassInfo2WrappedNativeProtoMap* mMainThreadWrappedNativeProtoMap;
-    nsXPCComponents*                 mComponents;
+    nsRefPtr<nsXPCComponents>        mComponents;
     XPCWrappedNativeScope*           mNext;
     // The JS global object for this scope.  If non-null, this will be the
     // default parent for the XPCWrappedNatives that have us as the scope,
     // unless a PreCreate hook overrides it.  Note that this _may_ be null (see
     // constructor).
     js::ObjectPtr                    mGlobalJSObject;
 
     // Cached value of Object.prototype
@@ -3889,20 +3890,22 @@ public:
                               XPCWrappedNativeScope* aScope,
                               JSObject* aGlobal);
 
     void SystemIsBeingShutDown() {ClearMembers();}
 
     virtual ~nsXPCComponents();
 
 private:
-    nsXPCComponents();
+    nsXPCComponents(XPCWrappedNativeScope* aScope);
     void ClearMembers();
 
 private:
+    friend class XPCWrappedNativeScope;
+    XPCWrappedNativeScope*          mScope;
     nsXPCComponents_Interfaces*     mInterfaces;
     nsXPCComponents_InterfacesByID* mInterfacesByID;
     nsXPCComponents_Classes*        mClasses;
     nsXPCComponents_ClassesByID*    mClassesByID;
     nsXPCComponents_Results*        mResults;
     nsXPCComponents_ID*             mID;
     nsXPCComponents_Exception*      mException;
     nsXPCComponents_Constructor*    mConstructor;