Bug 973780 - Implement an expando WeakMap on XPCWrappedNativeScope. r=mccr8
authorBobby Holley <bobbyholley@gmail.com>
Thu, 20 Feb 2014 18:24:09 -0800
changeset 170153 523e9ec89a9f02bc1b1b6e1d72733785e361bf08
parent 170152 8db4d719f5f853db811be590f262acfc356cfb0f
child 170154 29fbf3dac1ad376cf39faba4c3723efc49bccb5d
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersmccr8
bugs973780
milestone30.0a1
Bug 973780 - Implement an expando WeakMap on XPCWrappedNativeScope. r=mccr8
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -297,16 +297,19 @@ XPCWrappedNativeScope::~XPCWrappedNative
     // with the scope but just in case.
     if (mComponents)
         mComponents->mScope = nullptr;
 
     // XXX we should assert that we are dead or that xpconnect has shutdown
     // XXX might not want to do this at xpconnect shutdown time???
     mComponents = nullptr;
 
+    if (mXrayExpandos.initialized())
+        mXrayExpandos.destroy();
+
     JSRuntime *rt = XPCJSRuntime::Get()->Runtime();
     mXBLScope.finalize(rt);
     mGlobalJSObject.finalize(rt);
 }
 
 static PLDHashOperator
 WrappedNativeJSGCThingTracer(PLDHashTable *table, PLDHashEntryHdr *hdr,
                              uint32_t number, void *arg)
@@ -594,16 +597,37 @@ WNProtoRemover(PLDHashTable *table, PLDH
 
 void
 XPCWrappedNativeScope::RemoveWrappedNativeProtos()
 {
     mWrappedNativeProtoMap->Enumerate(WNProtoRemover,
                                       GetRuntime()->GetDetachedWrappedNativeProtoMap());
 }
 
+JSObject *
+XPCWrappedNativeScope::GetExpandoChain(JSObject *target)
+{
+    MOZ_ASSERT(GetObjectScope(target) == this);
+    if (!mXrayExpandos.initialized())
+        return nullptr;
+    return mXrayExpandos.lookup(target);
+}
+
+bool
+XPCWrappedNativeScope::SetExpandoChain(JSContext *cx, HandleObject target,
+                                       HandleObject chain)
+{
+    MOZ_ASSERT(GetObjectScope(target) == this);
+    MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
+    MOZ_ASSERT_IF(chain, GetObjectScope(chain) == this);
+    if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx))
+        return false;
+    return mXrayExpandos.put(target, chain);
+}
+
 /***************************************************************************/
 
 // static
 void
 XPCWrappedNativeScope::DebugDumpAllScopes(int16_t depth)
 {
 #ifdef DEBUG
     depth-- ;
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -85,16 +85,17 @@
 
 #include <math.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "xpcpublic.h"
 #include "js/Tracer.h"
+#include "js/WeakMapPtr.h"
 #include "pldhash.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"
 #include "nsISupports.h"
 #include "nsIServiceManager.h"
@@ -1031,29 +1032,37 @@ public:
     GetGlobalJSObjectPreserveColor() const {return mGlobalJSObject;}
 
     nsIPrincipal*
     GetPrincipal() const {
         JSCompartment *c = js::GetObjectCompartment(mGlobalJSObject);
         return nsJSPrincipals::get(JS_GetCompartmentPrincipals(c));
     }
 
+    JSObject*
+    GetExpandoChain(JSObject *target);
+
+    bool
+    SetExpandoChain(JSContext *cx, JS::HandleObject target, JS::HandleObject chain);
+
     void RemoveWrappedNativeProtos();
 
     static void
     SystemIsBeingShutDown();
 
     static void
     TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt);
 
     void TraceSelf(JSTracer *trc) {
         MOZ_ASSERT(mGlobalJSObject);
         mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
         if (mXBLScope)
             mXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
+        if (mXrayExpandos.initialized())
+            mXrayExpandos.trace(trc);
     }
 
     static void
     SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionNoteRootCallback &cb);
 
     static void
     StartFinalizationPhaseOfGC(JSFreeOp *fop, XPCJSRuntime* rt);
 
@@ -1163,16 +1172,18 @@ private:
     // EnsureXBLScope() decides whether it needs to be created or not.
     // This reference is wrapped into the compartment of mGlobalJSObject.
     JS::ObjectPtr                    mXBLScope;
 
     XPCContext*                      mContext;
 
     nsAutoPtr<DOMExpandoSet> mDOMExpandoSet;
 
+    JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
+
     bool mIsXBLScope;
 
     // For remote XUL domains, we run all XBL in the content scope for compat
     // reasons (though we sometimes pref this off for automation). We separately
     // track the result of this decision (mAllowXBLScope), from the decision
     // of whether to actually _use_ an XBL scope (mUseXBLScope), which depends
     // on the type of global and whether the compartment is system principal
     // or not.