Bug 617093 - Kill the dead XOW cache. r=jst
authorBlake Kaplan <mrbkap@gmail.com>
Mon, 06 Dec 2010 12:10:28 -0800
changeset 58747 e7c919ed72f119e1926e8f7c61224d4bfa8ecb46
parent 58746 0641328503d89713b0744e06f92c14ff882b910f
child 58748 cc202b48606f1cbbbfe8d110579935ac41fa4cc5
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjst
bugs617093
milestone2.0b8pre
Bug 617093 - Kill the dead XOW cache. r=jst
dom/base/nsDOMClassInfo.cpp
js/src/xpconnect/idl/nsIXPCScriptable.idl
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcwrappednative.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4941,17 +4941,17 @@ nsWindowSH::PreCreate(nsISupports *nativ
 
   nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
   if (win->IsOuterWindow()) {
     if (!win->EnsureInnerWindow()) {
       return NS_ERROR_FAILURE;
     }
 
     *parentObj = win->GetCurrentInnerWindowInternal()->FastGetGlobalJSObject();
-    return win->IsChromeWindow() ? NS_OK : NS_SUCCESS_NEEDS_XOW;
+    return NS_OK;
   }
 
   JSObject *winObj = win->FastGetGlobalJSObject();
   if (!winObj) {
     NS_ASSERTION(win->GetOuterWindowInternal()->IsCreatingInnerWindow(),
                  "should have a JS object by this point");
     return NS_OK;
   }
--- a/js/src/xpconnect/idl/nsIXPCScriptable.idl
+++ b/js/src/xpconnect/idl/nsIXPCScriptable.idl
@@ -59,23 +59,16 @@
  * Classes that want slim wrappers should return NS_SUCCESS_ALLOW_SLIM_WRAPPERS
  * from their scriptable helper's PreCreate hook. They must also force a parent
  * for their wrapper (from the PreCreate hook), they must implement
  * nsWrapperCache and their scriptable helper must implement nsXPCClassInfo and
  * must return DONT_ASK_INSTANCE_FOR_SCRIPTABLE in the flags.
  */
 #define NS_SUCCESS_ALLOW_SLIM_WRAPPERS \
    (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,3))
-
-/**
- * Classes that can change principals and require same-origin XOWs must return
- * this from their scriptable helper's PreCreate hook.
- */
-#define NS_SUCCESS_NEEDS_XOW \
-   (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,4))
 %}
 
 /**
  * Note: This is not really an XPCOM interface.  For example, callers must
  * guarantee that they set the *_retval of the various methods that return a
  * boolean to PR_TRUE before making the call.  Implementations may skip writing
  * to *_retval unless they want to return PR_FALSE.
  */
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -2693,31 +2693,28 @@ public:
                         XPCNativeScriptableCreateInfo& sciProto);
 
     JSBool HasExternalReference() const {return mRefCnt > 1;}
 
     JSBool NeedsSOW() { return !!(mWrapperWord & NEEDS_SOW); }
     void SetNeedsSOW() { mWrapperWord |= NEEDS_SOW; }
     JSBool NeedsCOW() { return !!(mWrapperWord & NEEDS_COW); }
     void SetNeedsCOW() { mWrapperWord |= NEEDS_COW; }
-    JSBool NeedsXOW() { return !!(mWrapperWord & NEEDS_XOW); }
 
     JSObject* GetWrapper()
     {
         return (JSObject *) (mWrapperWord & (size_t)~(size_t)FLAG_MASK);
     }
     void SetWrapper(JSObject *obj)
     {
         PRWord needsSOW = NeedsSOW() ? NEEDS_SOW : 0;
         PRWord needsCOW = NeedsCOW() ? NEEDS_COW : 0;
-        PRWord needsXOW = NeedsXOW() ? NEEDS_XOW : 0;
         mWrapperWord = PRWord(obj) |
                          needsSOW |
-                         needsCOW |
-                         needsXOW;
+                         needsCOW;
     }
 
     void NoteTearoffs(nsCycleCollectionTraversalCallback& cb);
 
     QITableEntry* GetOffsets()
     {
         if(!HasProto() || !GetProto()->ClassIsDOMObject())
             return nsnull;
@@ -2746,29 +2743,22 @@ protected:
                      XPCNativeSet* aSet);
 
     virtual ~XPCWrappedNative();
 
 private:
     enum {
         NEEDS_SOW = JS_BIT(0),
         NEEDS_COW = JS_BIT(1),
-        NEEDS_XOW = JS_BIT(2),
-
-        LAST_FLAG = NEEDS_XOW,
+
+        LAST_FLAG = NEEDS_COW,
 
         FLAG_MASK = 0x7
     };
 
-protected:
-    void SetNeedsXOW() {
-        NS_ASSERTION(mWrapperWord == 0, "It's too late to call this");
-        mWrapperWord = NEEDS_XOW;
-    }
-
 private:
 
     JSBool Init(XPCCallContext& ccx, JSObject* parent, JSBool isGlobal,
                 const XPCNativeScriptableCreateInfo* sci);
     JSBool Init(XPCCallContext &ccx, JSObject *existingJSObject);
     JSBool FinishInit(XPCCallContext &ccx);
 
     JSBool ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface);
@@ -2801,49 +2791,16 @@ private:
     PRWord                       mWrapperWord;
 
 #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
 public:
     nsCOMPtr<nsIThread>          mThread; // Don't want to overload _mOwningThread
 #endif
 };
 
-class XPCWrappedNativeWithXOW : public XPCWrappedNative
-{
-public:
-    XPCWrappedNativeWithXOW(already_AddRefed<nsISupports> aIdentity,
-                            XPCWrappedNativeProto* aProto)
-        : XPCWrappedNative(aIdentity, aProto),
-          mXOW(nsnull)
-    {
-        SetNeedsXOW();
-    }
-    XPCWrappedNativeWithXOW(already_AddRefed<nsISupports> aIdentity,
-                            XPCWrappedNativeScope* aScope,
-                            XPCNativeSet* aSet)
-        : XPCWrappedNative(aIdentity, aScope, aSet),
-          mXOW(nsnull)
-    {
-        SetNeedsXOW();
-    }
-
-    JSObject *GetXOW()
-    {
-        return mXOW;
-    }
-
-    void SetXOW(JSObject *xow)
-    {
-        mXOW = xow;
-    }
-
-private:
-    JSObject *mXOW;
-};
-
 /***************************************************************************
 ****************************************************************************
 *
 * Core classes for wrapped JSObject for use from native code...
 *
 ****************************************************************************
 ***************************************************************************/
 
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -422,32 +422,29 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
 
     JSObject* parent = Scope->GetGlobalJSObject();
 
     jsval newParentVal = JSVAL_NULL;
     XPCMarkableJSVal newParentVal_markable(&newParentVal);
     AutoMarkingJSVal newParentVal_automarker(ccx, &newParentVal_markable);
     JSBool needsSOW = JS_FALSE;
     JSBool needsCOW = JS_FALSE;
-    JSBool needsXOW = JS_FALSE;
 
     JSAutoEnterCompartment ac;
 
     if(sciWrapper.GetFlags().WantPreCreate())
     {
         JSObject* plannedParent = parent;
         nsresult rv = sciWrapper.GetCallback()->PreCreate(identity, ccx,
                                                           parent, &parent);
         if(NS_FAILED(rv))
             return rv;
 
         if(rv == NS_SUCCESS_CHROME_ACCESS_ONLY)
             needsSOW = JS_TRUE;
-        else if(rv == NS_SUCCESS_NEEDS_XOW)
-            needsXOW = JS_TRUE;
         rv = NS_OK;
 
         NS_ASSERTION(!xpc::WrapperFactory::IsXrayWrapper(parent),
                      "Xray wrapper being used to parent XPCWrappedNative?");
 
         if(!ac.enter(ccx, parent))
             return NS_ERROR_FAILURE;
 
@@ -539,37 +536,33 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     {
         proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, Scope, info, &sciProto,
                                                     JS_FALSE, isGlobal);
         if(!proto)
             return NS_ERROR_FAILURE;
 
         proto->CacheOffsets(identity);
 
-        wrapper = needsXOW
-                  ? new XPCWrappedNativeWithXOW(identity, proto)
-                  : new XPCWrappedNative(identity, proto);
+        wrapper = new XPCWrappedNative(identity, proto);
         if(!wrapper)
             return NS_ERROR_FAILURE;
     }
     else
     {
         AutoMarkingNativeInterfacePtr iface(ccx, Interface);
         if(!iface)
             iface = XPCNativeInterface::GetISupports(ccx);
 
         AutoMarkingNativeSetPtr set(ccx);
         set = XPCNativeSet::GetNewOrUsed(ccx, nsnull, iface, 0);
 
         if(!set)
             return NS_ERROR_FAILURE;
 
-        wrapper = needsXOW
-                  ? new XPCWrappedNativeWithXOW(identity, Scope, set)
-                  : new XPCWrappedNative(identity, Scope, set);
+        wrapper = new XPCWrappedNative(identity, Scope, set);
         if(!wrapper)
             return NS_ERROR_FAILURE;
 
         DEBUG_ReportShadowedMembers(set, wrapper, nsnull);
     }
 
     // The strong reference was taken over by the wrapper, so make the nsCOMPtr
     // forget about it.
@@ -1352,31 +1345,16 @@ XPCWrappedNative::FlatJSObjectFinalized(
     nsWrapperCache *cache = nsnull;
     CallQueryInterface(mIdentity, &cache);
     if(cache)
         cache->ClearWrapper();
 
     // This makes IsValid return false from now on...
     mFlatJSObject = nsnull;
 
-    // Because order of finalization is random, we need to be careful here: if
-    // we're getting finalized, then it means that any XOWs in our cache are
-    // also getting finalized (or else we would be marked). But it's possible
-    // for us to outlive our cached XOW. So, in order to make it safe for the
-    // cached XOW to clear the cache, we need to finalize it first.
-    if(NeedsXOW())
-    {
-        XPCWrappedNativeWithXOW* wnxow =
-            static_cast<XPCWrappedNativeWithXOW *>(this);
-        if(JSObject* wrapper = wnxow->GetXOW())
-        {
-            wrapper->getClass()->finalize(cx, wrapper);
-        }
-    }
-
     NS_ASSERTION(mIdentity, "bad pointer!");
 #ifdef XP_WIN
     // Try to detect free'd pointer
     NS_ASSERTION(*(int*)mIdentity != 0xdddddddd, "bad pointer!");
     NS_ASSERTION(*(int*)mIdentity != 0,          "bad pointer!");
 #endif
 
     // Note that it's not safe to touch mNativeWrapper here since it's