diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 86f8aa0ef7c6..c73e8f52c75f 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -101,8 +101,8 @@ 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) @@ -125,7 +125,8 @@ public: mCompatMode(eCompatibility_FullStandards), mIsInitialDocumentInWindow(PR_FALSE), mMayStartLayout(PR_TRUE), - mPartID(0) + mPartID(0), + mJSObject(nsnull) { mParentPtrBits |= PARENT_BIT_INDOCUMENT; } @@ -994,6 +995,16 @@ public: 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 GetFragmentParser() { @@ -1236,6 +1247,12 @@ protected: nsCOMPtr 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) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index cbd3489d40af..dbe9bb9ba069 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -6986,13 +6986,8 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj, // to wrap here? But that's not always reachable, let's use // globalObj for now... - nsIXPConnectJSObjectHolder *wrapper; - if (native_parent == doc && - (wrapper = static_cast(doc->GetWrapper()))) { - wrapper->GetJSObject(parentObj); - if(*parentObj) { - return NS_OK; - } + if (native_parent == doc && (*parentObj = doc->GetJSObject())) { + return NS_OK; } jsval v; @@ -8256,6 +8251,10 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, 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); @@ -8289,6 +8288,20 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return NS_OK; } +NS_IMETHODIMP +nsDocumentSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx, + JSObject *obj) +{ + nsCOMPtr doc = do_QueryWrappedNative(wrapper); + if (!doc) { + return NS_ERROR_UNEXPECTED; + } + + doc->SetJSObject(nsnull); + + return nsNodeSH::Finalize(wrapper, cx, obj); +} + // HTMLDocument helper // static diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index 5205ee53cdb3..a47d64b71a83 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -864,6 +864,8 @@ public: 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) { diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 993471d93b14..2d606c6aae28 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -73,7 +73,7 @@ public: * including nsIXPConnect, because we don't want to make everyone require * JS and XPConnect. */ - nsISupports* GetWrapper() const + nsISupports* GetWrapper() { return reinterpret_cast(mWrapperPtrBits & ~kWrapperBitMask); }