Backing out 18b1811cd104, fix for bug 480389 (Remove nsIDocument's cached JS object), to try to fix orange.
authorPeter Van der Beken <peterv@propagandism.org>
Thu, 19 Mar 2009 14:07:03 +0100
changeset 26357 f69b7bcdcf223a39eca8edd2a47b5ba8ec748e06
parent 26351 18b1811cd1042e4b4f6f0444f865683c2683d11d
child 26358 cc39595b8ee7fcb9f40552c3e57b377e9819a87e
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs480389
milestone1.9.2a1pre
Backing out 18b1811cd104, fix for bug 480389 (Remove nsIDocument's cached JS object), to try to fix orange.
content/base/public/nsIDocument.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsWrapperCache.h
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -96,18 +96,18 @@ class nsIDocumentObserver;
 class nsBindingManager;
 class nsIDOMNodeList;
 class mozAutoSubtreeModified;
 struct JSObject;
 class nsFrameLoader;
 
 // IID for the nsIDocument interface
 #define NS_IDOCUMENT_IID      \
-{ 0x6e467d95, 0x9934, 0x422a, \
- { 0x81, 0x07, 0x3f, 0xff, 0xe1, 0x38, 0xe6, 0x1e } }
+{ 0xdd9bd470, 0x6315, 0x4e67, \
+  { 0xa8, 0x8a, 0x78, 0xbf, 0x92, 0xb4, 0x5a, 0xdf } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
@@ -120,17 +120,18 @@ public:
 #ifdef MOZILLA_INTERNAL_API
   nsIDocument()
     : nsINode(nsnull),
       mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
       mNodeInfoManager(nsnull),
       mCompatMode(eCompatibility_FullStandards),
       mIsInitialDocumentInWindow(PR_FALSE),
       mMayStartLayout(PR_TRUE),
-      mPartID(0)
+      mPartID(0),
+      mJSObject(nsnull)
   {
     mParentPtrBits |= PARENT_BIT_INDOCUMENT;
   }
 #endif
   
   /**
    * Let the document know that we're starting to load data into it.
    * @param aCommand The parser command
@@ -989,16 +990,26 @@ public:
     return mMayStartLayout;
   }
 
   void SetMayStartLayout(PRBool aMayStartLayout)
   {
     mMayStartLayout = aMayStartLayout;
   }
 
+  JSObject* GetJSObject() const
+  {
+    return mJSObject;
+  }
+
+  void SetJSObject(JSObject *aJSObject)
+  {
+    mJSObject = aJSObject;
+  }
+
   // This method should return an addrefed nsIParser* or nsnull. Implementations
   // should transfer ownership of the parser to the caller.
   virtual already_AddRefed<nsIParser> GetFragmentParser() {
     return nsnull;
   }
 
   virtual void SetFragmentParser(nsIParser* aParser) {
     // Do nothing.
@@ -1231,16 +1242,22 @@ protected:
   PRUint32            mSubtreeModifiedDepth;
 
   // If we're an external resource document, this will be non-null and will
   // point to our "display document": the one that all resource lookups should
   // go to.
   nsCOMPtr<nsIDocument> mDisplayDocument;
 
   PRUint32 mEventsSuppressed;
+
+private:
+  // JSObject cache. Only to be used for performance
+  // optimizations. This will be set once this document is touched
+  // from JS, and it will be unset once the JSObject is finalized.
+  JSObject *mJSObject;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
 
 /**
  * mozAutoSubtreeModified batches DOM mutations so that a DOMSubtreeModified
  * event is dispatched, if necessary, when the outermost mozAutoSubtreeModified
  * object is deleted.
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -6981,23 +6981,18 @@ nsNodeSH::PreCreate(nsISupports *nativeO
     }
   }
 
   // XXXjst: Maybe we need to find the global to use from the
   // nsIScriptGlobalObject that's reachable from the node we're about
   // to wrap here? But that's not always reachable, let's use
   // globalObj for now...
 
-  nsIXPConnectJSObjectHolder *wrapper;
-  if (native_parent == doc &&
-      (wrapper = static_cast<nsIXPConnectJSObjectHolder*>(doc->GetWrapper()))) {
-    wrapper->GetJSObject(parentObj);
-    if(*parentObj) {
-      return NS_OK;
-    }
+  if (native_parent == doc && (*parentObj = doc->GetJSObject())) {
+    return NS_OK;
   }
 
   jsval v;
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   nsresult rv = WrapNative(cx, globalObj, native_parent, &v,
                            getter_AddRefs(holder));
 
   *parentObj = JSVAL_TO_OBJECT(v);
@@ -8251,16 +8246,20 @@ nsDocumentSH::PostCreate(nsIXPConnectWra
   // object of this document, then define this document object on the window.
   // That will make sure that the document is referenced (via window.document)
   // and prevent it from going away in GC.
   nsCOMPtr<nsIDocument> doc = do_QueryWrappedNative(wrapper);
   if (!doc) {
     return NS_ERROR_UNEXPECTED;
   }
 
+  // Cache the document's JSObject on the document so we can optimize
+  // nsNodeSH::PreCreate() to avoid nested WrapNative() calls.
+  doc->SetJSObject(obj);
+
   nsresult rv = nsNodeSH::PostCreate(wrapper, cx, obj);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
   nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(sgo);
   if (!win) {
     // No window, nothing else to do here
     return NS_OK;
@@ -8284,16 +8283,30 @@ nsDocumentSH::PostCreate(nsIXPConnectWra
                                doc_str.Length(), OBJECT_TO_JSVAL(obj), nsnull,
                                nsnull, JSPROP_READONLY | JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDocumentSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
+                       JSObject *obj)
+{
+  nsCOMPtr<nsIDocument> doc = do_QueryWrappedNative(wrapper);
+  if (!doc) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  doc->SetJSObject(nsnull);
+
+  return nsNodeSH::Finalize(wrapper, cx, obj);
+}
+
 // HTMLDocument helper
 
 // static
 nsresult
 nsHTMLDocumentSH::ResolveImpl(JSContext *cx,
                               nsIXPConnectWrappedNative *wrapper, jsval id,
                               nsISupports **result)
 {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -859,16 +859,18 @@ public:
                         JSObject **objp, PRBool *_retval);
   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
   NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
   NS_IMETHOD GetFlags(PRUint32* aFlags);
   NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                         JSObject *obj);
+  NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
+                      JSObject *obj);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsDocumentSH(aData);
   }
 };
 
 
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -68,17 +68,17 @@ public:
     }
   }
 
   /**
    * This method returns an nsIXPConnectWrappedNative, but we want to avoid
    * including nsIXPConnect, because we don't want to make everyone require
    * JS and XPConnect.
    */
-  nsISupports* GetWrapper() const
+  nsISupports* GetWrapper()
   {
     return reinterpret_cast<nsISupports*>(mWrapperPtrBits & ~kWrapperBitMask);
   }
 
   /**
    * This method takes an nsIXPConnectWrappedNative, but we want to avoid
    * including nsIXPConnect, because we don't want to make everyone require
    * JS and XPConnect.