mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Fixing leak introduced by the fix for bug 256932. Make sure we release the document pointer held by the global scope polluter holds as private data early enough to let the document do its cleanup before it's too late during shutdown. r=brendan@mozilla.org, sr=dbaron@dbaron.org
This commit is contained in:
parent
78e6b08b52
commit
376c9e5ad7
@ -3470,20 +3470,49 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
JSObject *
|
||||
nsWindowSH::GetInvalidatedGlobalScopePolluter(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto;
|
||||
|
||||
while ((proto = ::JS_GetPrototype(cx, obj))) {
|
||||
if (JS_GET_CLASS(cx, proto) == &sGlobalScopePolluterClass) {
|
||||
nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(cx, proto);
|
||||
|
||||
NS_IF_RELEASE(doc);
|
||||
|
||||
::JS_SetPrivate(cx, proto, nsnull);
|
||||
|
||||
::JS_ClearScope(cx, proto);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
obj = proto;
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
|
||||
JSObject *oldPolluter,
|
||||
nsIHTMLDocument *doc)
|
||||
{
|
||||
// If we didn't get a document, don't bother setting up a global
|
||||
// scope polluter.
|
||||
if (!doc || sDisableGlobalScopePollutionSupport) {
|
||||
// If global scope pollution is disabled, do nothing
|
||||
if (sDisableGlobalScopePollutionSupport) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject *gsp = ::JS_NewObject(cx, &sGlobalScopePolluterClass, nsnull, obj);
|
||||
JSObject *gsp = oldPolluter;
|
||||
|
||||
if (!gsp) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
gsp = ::JS_NewObject(cx, &sGlobalScopePolluterClass, nsnull, obj);
|
||||
if (!gsp) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
JSObject *o = obj, *proto;
|
||||
@ -3504,7 +3533,7 @@ nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
|
||||
o = proto;
|
||||
}
|
||||
|
||||
// And then set the ptototype of the object whose prototype was
|
||||
// And then set the prototype of the object whose prototype was
|
||||
// Object.prototype to be the global scope polluter.
|
||||
if (!::JS_SetPrototype(cx, o, gsp)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@ -3516,7 +3545,7 @@ nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
|
||||
|
||||
// The global scope polluter will release doc on destruction (or
|
||||
// reinitialzation).
|
||||
NS_ADDREF(doc);
|
||||
NS_IF_ADDREF(doc);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -4489,9 +4518,7 @@ nsWindowSH::OnDocumentChanged(JSContext *cx, JSObject *obj,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(document));
|
||||
|
||||
return InstallGlobalScopePolluter(cx, obj, html_doc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -373,7 +373,10 @@ public:
|
||||
static JSBool JS_DLL_CALLBACK SecurityCheckOnSetProp(JSContext *cx,
|
||||
JSObject *obj, jsval id,
|
||||
jsval *vp);
|
||||
static JSObject *GetInvalidatedGlobalScopePolluter(JSContext *cx,
|
||||
JSObject *obj);
|
||||
static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
|
||||
JSObject *oldPolluter,
|
||||
nsIHTMLDocument *doc);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocCharset.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDOMCrypto.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
@ -602,9 +603,19 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument,
|
||||
getter_AddRefs(mNavigatorHolder));
|
||||
}
|
||||
|
||||
JSObject *gsp =
|
||||
nsWindowSH::GetInvalidatedGlobalScopePolluter(cx, mJSObject);
|
||||
|
||||
::JS_ClearScope(cx, mJSObject);
|
||||
::JS_ClearRegExpStatics(cx);
|
||||
|
||||
if (gsp) {
|
||||
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument));
|
||||
|
||||
nsWindowSH::InstallGlobalScopePolluter(cx, mJSObject, gsp,
|
||||
html_doc);
|
||||
}
|
||||
|
||||
mIsScopeClear = PR_TRUE;
|
||||
}
|
||||
}
|
||||
@ -642,18 +653,23 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument,
|
||||
mDocument = aDocument;
|
||||
|
||||
if (mDocument && mContext) {
|
||||
JSObject *gsp =
|
||||
nsWindowSH::GetInvalidatedGlobalScopePolluter(cx, mJSObject);
|
||||
|
||||
if (mIsScopeClear) {
|
||||
mContext->InitContext(this);
|
||||
} else {
|
||||
// If we didn't clear the scope (i.e. the old document was
|
||||
// about:blank) then we need to update the cached document
|
||||
// property on the window to reflect the new document and not the
|
||||
// old one.
|
||||
|
||||
nsWindowSH::OnDocumentChanged(cx, mJSObject, this);
|
||||
}
|
||||
|
||||
// If we didn't clear the scope (i.e. the old document was
|
||||
// about:blank) then we need to update the cached document
|
||||
// property on the window to reflect the new document and not the
|
||||
// old one. And even if we did clear the scope, we need to notify
|
||||
// the scriptable helper about the document change.
|
||||
nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument));
|
||||
|
||||
nsWindowSH::OnDocumentChanged(cx, mJSObject, this);
|
||||
nsWindowSH::InstallGlobalScopePolluter(cx, mJSObject, gsp, html_doc);
|
||||
}
|
||||
|
||||
// Clear our mutation bitfield.
|
||||
|
Loading…
Reference in New Issue
Block a user