зеркало из https://github.com/mozilla/pjs.git
Fixing one more part of the DOM performance bug 118933. Cache the properties 'document' and 'window' on the global object in JS to avoid needing to go through XPConnect every time these are accessed. 2x speedup on some DOM testcases where the bulk of the time we spend is in the JS engine and XPConnect. r=peterv@netscape.com, sr=vidur@netscape.com
This commit is contained in:
Родитель
d7ab4fab24
Коммит
5909fbe828
|
@ -839,6 +839,8 @@ JSString *nsDOMClassInfo::sOpen_id = nsnull;
|
|||
JSString *nsDOMClassInfo::sItem_id = nsnull;
|
||||
JSString *nsDOMClassInfo::sEnumerate_id = nsnull;
|
||||
JSString *nsDOMClassInfo::sNavigator_id = nsnull;
|
||||
JSString *nsDOMClassInfo::sDocument_id = nsnull;
|
||||
JSString *nsDOMClassInfo::sWindow_id = nsnull;
|
||||
|
||||
const JSClass *nsDOMClassInfo::sObjectClass = nsnull;
|
||||
|
||||
|
@ -913,6 +915,8 @@ nsDOMClassInfo::DefineStaticJSStrings(JSContext *cx)
|
|||
sItem_id = ::JS_InternString(cx, "item");
|
||||
sEnumerate_id = ::JS_InternString(cx, "enumerateProperties");
|
||||
sNavigator_id = ::JS_InternString(cx, "navigator");
|
||||
sDocument_id = ::JS_InternString(cx, "document");
|
||||
sWindow_id = ::JS_InternString(cx, "window");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2666,6 +2670,8 @@ nsDOMClassInfo::ShutDown()
|
|||
sItem_id = jsnullstring;
|
||||
sEnumerate_id = jsnullstring;
|
||||
sNavigator_id = jsnullstring;
|
||||
sDocument_id = jsnullstring;
|
||||
sWindow_id = jsnullstring;
|
||||
|
||||
NS_IF_RELEASE(sXPConnect);
|
||||
NS_IF_RELEASE(sSecMan);
|
||||
|
@ -2769,10 +2775,13 @@ nsWindowSH::doCheckPropertyAccess(JSContext *cx, JSObject *obj, jsval id,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't check when getting the Components property,
|
||||
// since we check its properties anyway. This will help performance.
|
||||
// Don't check when getting the document, window, or Components
|
||||
// property, since we check its properties anyway. This will help
|
||||
// performance.
|
||||
if (accessMode == nsIXPCSecurityManager::ACCESS_GET_PROPERTY &&
|
||||
id == STRING_TO_JSVAL(sComponents_id)) {
|
||||
(id == STRING_TO_JSVAL(sDocument_id) ||
|
||||
id == STRING_TO_JSVAL(sWindow_id) ||
|
||||
id == STRING_TO_JSVAL(sComponents_id))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2977,7 +2986,8 @@ nsWindowSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = doCheckPropertyAccess(cx, obj, id, wrapper,
|
||||
nsresult rv =
|
||||
doCheckPropertyAccess(cx, obj, id, wrapper,
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -2996,7 +3006,8 @@ nsWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
PRBool *_retval)
|
||||
{
|
||||
|
||||
nsresult rv = doCheckPropertyAccess(cx, obj, id, wrapper,
|
||||
nsresult rv =
|
||||
doCheckPropertyAccess(cx, obj, id, wrapper,
|
||||
nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -3565,6 +3576,31 @@ nsWindowSH::GlobalResolve(nsISupports *native, JSContext *cx, JSObject *obj,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsWindowSH::CacheDocumentProperty(JSContext *cx, JSObject *obj,
|
||||
nsIDOMWindow *window)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
nsresult rv = window->GetDocument(getter_AddRefs(document));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
jsval v;
|
||||
rv = WrapNative(cx, obj, document, NS_GET_IID(nsIDOMDocument), &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(doc_str, "document");
|
||||
|
||||
if (!::JS_DefineUCProperty(cx, obj, NS_REINTERPRET_CAST(const jschar *,
|
||||
doc_str.get()),
|
||||
doc_str.Length(), v, nsnull,
|
||||
nsnull, JSPROP_READONLY)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, PRUint32 flags,
|
||||
|
@ -3777,6 +3813,34 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (str == sDocument_id) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(native));
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rv = CacheDocumentProperty(cx, obj, window);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*objp = obj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (str == sWindow_id) {
|
||||
jsval v;
|
||||
rv = WrapNative(cx, obj, native, NS_GET_IID(nsIDOMWindow), &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
|
||||
::JS_GetStringLength(str), v, nsnull,
|
||||
nsnull, JSPROP_READONLY)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return nsEventRecieverSH::NewResolve(wrapper, cx, obj, id, flags, objp,
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "jsapi.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsIDOMNSHTMLOptionCollection;
|
||||
class nsIPluginInstance;
|
||||
class nsIForm;
|
||||
|
@ -233,6 +234,8 @@ protected:
|
|||
static JSString *sItem_id;
|
||||
static JSString *sEnumerate_id;
|
||||
static JSString *sNavigator_id;
|
||||
static JSString *sDocument_id;
|
||||
static JSString *sWindow_id;
|
||||
|
||||
|
||||
static const JSClass *sObjectClass;
|
||||
|
@ -323,6 +326,9 @@ public:
|
|||
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
|
||||
static nsresult CacheDocumentProperty(JSContext *cx, JSObject *obj,
|
||||
nsIDOMWindow *window);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
return new nsWindowSH(aData);
|
||||
|
|
|
@ -479,7 +479,9 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument,
|
|||
// not doing this unless there's a new document prevents a closed window's
|
||||
// JS properties from going away (that's good) and causes everything,
|
||||
// and I mean everything, to be leaked (that's bad)
|
||||
::JS_ClearScope((JSContext *)mContext->GetNativeContext(), mJSObject);
|
||||
|
||||
::JS_ClearScope((JSContext *)mContext->GetNativeContext(),
|
||||
mJSObject);
|
||||
|
||||
mIsScopeClear = PR_TRUE;
|
||||
}
|
||||
|
@ -498,8 +500,19 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument,
|
|||
|
||||
mDocument = aDocument;
|
||||
|
||||
if (mDocument && mContext && mIsScopeClear) {
|
||||
if (mDocument && mContext) {
|
||||
if (mIsScopeClear) {
|
||||
mContext->InitContext(this);
|
||||
} else if (mJSObject) {
|
||||
// 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.
|
||||
|
||||
JSContext *cx = (JSContext *)mContext->GetNativeContext();
|
||||
|
||||
nsWindowSH::CacheDocumentProperty(cx, mJSObject, this);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear our mutation bitfield.
|
||||
|
|
Загрузка…
Ссылка в новой задаче