mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Fix for bug 590612 (Speed up js-wrapping in classinfo when we already have a wrapper). r=bz, a=jst.
This commit is contained in:
parent
68c6411e7f
commit
a6974efb9d
@ -106,12 +106,6 @@ nsIStringBundle *nsScriptSecurityManager::sStrBundle = nsnull;
|
||||
JSRuntime *nsScriptSecurityManager::sRuntime = 0;
|
||||
PRBool nsScriptSecurityManager::sStrictFileOriginPolicy = PR_TRUE;
|
||||
|
||||
// Info we need about the JSClasses used by XPConnects wrapped
|
||||
// natives, to avoid having to QI to nsIXPConnectWrappedNative all the
|
||||
// time when doing security checks.
|
||||
static JSEqualityOp sXPCWrappedNativeEqualityOps;
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Convenience Functions //
|
||||
///////////////////////////
|
||||
@ -2414,11 +2408,8 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
|
||||
do {
|
||||
// Note: jsClass is set before this loop, and also at the
|
||||
// *end* of this loop.
|
||||
|
||||
// NOTE: These class and equality hook checks better match
|
||||
// what IS_WRAPPER_CLASS() does in xpconnect!
|
||||
|
||||
if (jsClass->ext.equality == js::Valueify(sXPCWrappedNativeEqualityOps)) {
|
||||
if (IS_WRAPPER_CLASS(jsClass)) {
|
||||
result = sXPConnect->GetPrincipal(aObj,
|
||||
#ifdef DEBUG
|
||||
aAllowShortCircuit
|
||||
@ -3423,7 +3414,6 @@ nsresult nsScriptSecurityManager::Init()
|
||||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||
|
||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -5537,6 +5537,11 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject *wrapper = xpc_GetCachedSlimWrapper(cache, scope, vp);
|
||||
if (wrapper) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(sXPConnect && sThreadJSContextStack, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Keep sXPConnect and sThreadJSContextStack alive. If we're on the main
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsIDOMNSHTMLOptionCollection;
|
||||
@ -140,8 +141,8 @@ public:
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull)
|
||||
{
|
||||
return nsContentUtils::WrapNative(cx, scope, native, aIID, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
return WrapNative(cx, scope, native, nsnull, aIID, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
|
||||
// Used for cases where PreCreate needs to wrap the native parent, and the
|
||||
@ -161,8 +162,8 @@ public:
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull)
|
||||
{
|
||||
return nsContentUtils::WrapNative(cx, scope, native, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
return WrapNative(cx, scope, native, nsnull, nsnull, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
static nsresult WrapNative(JSContext *cx, JSObject *scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
@ -171,8 +172,8 @@ public:
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull)
|
||||
{
|
||||
return nsContentUtils::WrapNative(cx, scope, native, cache, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
return WrapNative(cx, scope, native, cache, nsnull, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
|
||||
static nsresult ThrowJSException(JSContext *cx, nsresult aResult);
|
||||
@ -247,6 +248,29 @@ protected:
|
||||
id == sName_id);
|
||||
}
|
||||
|
||||
static nsresult WrapNative(JSContext *cx, JSObject *scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
const nsIID* aIID, jsval *vp,
|
||||
nsIXPConnectJSObjectHolder** aHolder,
|
||||
PRBool aAllowWrapping)
|
||||
{
|
||||
if (!native) {
|
||||
NS_ASSERTION(!aHolder || !*aHolder, "*aHolder should be null!");
|
||||
|
||||
*vp = JSVAL_NULL;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject *wrapper = xpc_GetCachedSlimWrapper(cache, scope, vp);
|
||||
if (wrapper) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return sXPConnect->WrapNativeToJSVal(cx, scope, native, cache, aIID,
|
||||
aAllowWrapping, vp, aHolder);
|
||||
}
|
||||
|
||||
static nsIXPConnect *sXPConnect;
|
||||
static nsIScriptSecurityManager *sSecMan;
|
||||
|
||||
|
@ -40,19 +40,19 @@
|
||||
#ifndef jstl_h_
|
||||
#define jstl_h_
|
||||
|
||||
/* Gross special case for Gecko, which defines malloc/calloc/free. */
|
||||
#ifdef mozilla_mozalloc_macro_wrappers_h
|
||||
# define JS_UNDEFD_MOZALLOC_WRAPPERS
|
||||
/* The "anti-header" */
|
||||
# include "mozilla/mozalloc_undef_macro_wrappers.h"
|
||||
#endif
|
||||
|
||||
#include "jsbit.h"
|
||||
#include "jsstaticcheck.h"
|
||||
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
|
||||
/* Gross special case for Gecko, which defines malloc/calloc/free. */
|
||||
#ifdef mozilla_mozalloc_macro_wrappers_h
|
||||
# define JSSTL_UNDEFD_MOZALLOC_WRAPPERS
|
||||
/* The "anti-header" */
|
||||
# include "mozilla/mozalloc_undef_macro_wrappers.h"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
/* JavaScript Template Library. */
|
||||
@ -467,4 +467,8 @@ InitConst(const T &t)
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#ifdef JSSTL_UNDEFD_MOZALLOC_WRAPPERS
|
||||
# include "mozilla/mozalloc_macro_wrappers.h"
|
||||
#endif
|
||||
|
||||
#endif /* jstl_h_ */
|
||||
|
@ -50,6 +50,12 @@
|
||||
#pragma warning(disable:4345)
|
||||
#endif
|
||||
|
||||
/* Gross special case for Gecko, which defines malloc/calloc/free. */
|
||||
#ifdef mozilla_mozalloc_macro_wrappers_h
|
||||
# define JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS
|
||||
# include "mozilla/mozalloc_undef_macro_wrappers.h"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
@ -743,4 +749,8 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS
|
||||
# include "mozilla/mozalloc_macro_wrappers.h"
|
||||
#endif
|
||||
|
||||
#endif /* jsvector_h_ */
|
||||
|
@ -707,17 +707,8 @@ def writeResultConv(f, type, jsvalPtr, jsvalRef):
|
||||
return
|
||||
else:
|
||||
f.write(" nsWrapperCache* cache = xpc_qsGetWrapperCache(result);\n"
|
||||
" if (cache) {\n"
|
||||
" JSObject* wrapper = cache->GetWrapper();\n"
|
||||
" NS_ASSERTION(cx->compartment == obj->compartment(),\n"
|
||||
" \"wrong compartment in object or context!\");\n"
|
||||
" if (wrapper &&\n"
|
||||
# FIXME: Bug 585786, this check should go away
|
||||
" IS_SLIM_WRAPPER_OBJECT(wrapper) &&\n"
|
||||
" cx->compartment == wrapper->compartment()) {\n"
|
||||
" *%s = OBJECT_TO_JSVAL(wrapper);\n"
|
||||
" return JS_TRUE;\n"
|
||||
" }\n"
|
||||
" if (xpc_GetCachedSlimWrapper(cache, obj, %s)) {\n"
|
||||
" return JS_TRUE;\n"
|
||||
" }\n"
|
||||
" // After this point do not use 'result'!\n"
|
||||
" qsObjectHelper helper(result, cache);\n"
|
||||
@ -1259,17 +1250,10 @@ def writeTraceableResultConv(f, type):
|
||||
"&vp.array[0]);\n")
|
||||
else:
|
||||
f.write(" nsWrapperCache* cache = xpc_qsGetWrapperCache(result);\n"
|
||||
" if (cache) {\n"
|
||||
" JSObject* wrapper = cache->GetWrapper();\n"
|
||||
" NS_ASSERTION(cx->compartment == obj->compartment(),\n"
|
||||
" \"wrong compartment in object or context!\");\n"
|
||||
" if (wrapper &&\n"
|
||||
# FIXME: Bug 585786, this check should go away
|
||||
" IS_SLIM_WRAPPER_OBJECT(wrapper) &&\n"
|
||||
" cx->compartment == wrapper->compartment()) {\n"
|
||||
" vp.array[0] = OBJECT_TO_JSVAL(wrapper);\n"
|
||||
" return wrapper;\n"
|
||||
" }\n"
|
||||
" JSObject* wrapper =\n"
|
||||
" xpc_GetCachedSlimWrapper(cache, obj, &vp.array[0]);\n"
|
||||
" if (wrapper) {\n"
|
||||
" return wrapper;\n"
|
||||
" }\n"
|
||||
" // After this point do not use 'result'!\n"
|
||||
" qsObjectHelper helper(result, cache);\n"
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
#include "xpcpublic.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsprf.h"
|
||||
@ -1454,46 +1455,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj);
|
||||
(clazz) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass)
|
||||
|
||||
// NOTE!!!
|
||||
//
|
||||
// If this ever changes,
|
||||
// nsScriptSecurityManager::doGetObjectPrincipal() *must* be updated
|
||||
// also!
|
||||
//
|
||||
// NOTE!!!
|
||||
#define IS_WRAPPER_CLASS(clazz) \
|
||||
(clazz->ext.equality == js::Valueify(XPC_WN_Equality))
|
||||
|
||||
inline JSBool
|
||||
DebugCheckWrapperClass(JSObject* obj)
|
||||
{
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(obj->getClass()),
|
||||
"Forgot to check if this is a wrapper?");
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// If IS_WRAPPER_CLASS for the JSClass of an object is true, the object can be
|
||||
// a slim wrapper, holding a native in its private slot, or a wrappednative
|
||||
// wrapper, holding the XPCWrappedNative in its private slot. A slim wrapper
|
||||
// also holds a pointer to its XPCWrappedNativeProto in a reserved slot, we can
|
||||
// check that slot for a non-void value to distinguish between the two.
|
||||
|
||||
// Only use these macros if IS_WRAPPER_CLASS(obj->getClass()) is true.
|
||||
#define IS_WN_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && \
|
||||
obj->getSlot(0).isUndefined())
|
||||
#define IS_SLIM_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && \
|
||||
!obj->getSlot(0).isUndefined())
|
||||
|
||||
// Use these macros if IS_WRAPPER_CLASS(obj->getClass()) might be false.
|
||||
// Avoid calling them if IS_WRAPPER_CLASS(obj->getClass()) can only be
|
||||
// true, as we'd do a redundant call to IS_WRAPPER_CLASS.
|
||||
#define IS_WN_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(obj->getClass()) && IS_WN_WRAPPER_OBJECT(obj))
|
||||
#define IS_SLIM_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(obj->getClass()) && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
|
||||
// Comes from xpcwrappednativeops.cpp
|
||||
extern void
|
||||
xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper);
|
||||
@ -2463,7 +2424,6 @@ private:
|
||||
};
|
||||
|
||||
void *xpc_GetJSPrivate(JSObject *obj);
|
||||
inline JSObject *xpc_GetGlobalForObject(JSObject *obj);
|
||||
|
||||
/***************************************************************************/
|
||||
// XPCWrappedNative the wrapper around one instance of a native xpcom object
|
||||
@ -4457,13 +4417,6 @@ xpc_GetJSPrivate(JSObject *obj)
|
||||
{
|
||||
return obj->getPrivate();
|
||||
}
|
||||
inline JSObject *
|
||||
xpc_GetGlobalForObject(JSObject *obj)
|
||||
{
|
||||
while(JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XPCONNECT_STANDALONE
|
||||
|
@ -41,7 +41,10 @@
|
||||
#define xpcpublic_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsISupports.h"
|
||||
#include "jsobj.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
@ -56,4 +59,65 @@ xpc_CreateMTGlobalObject(JSContext *cx, JSClass *clasp,
|
||||
nsISupports *ptr, JSObject **global,
|
||||
JSCompartment **compartment);
|
||||
|
||||
extern JSBool
|
||||
XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
|
||||
|
||||
#define IS_WRAPPER_CLASS(clazz) \
|
||||
(clazz->ext.equality == js::Valueify(XPC_WN_Equality))
|
||||
|
||||
inline JSBool
|
||||
DebugCheckWrapperClass(JSObject* obj)
|
||||
{
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(obj->getClass()),
|
||||
"Forgot to check if this is a wrapper?");
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// If IS_WRAPPER_CLASS for the JSClass of an object is true, the object can be
|
||||
// a slim wrapper, holding a native in its private slot, or a wrappednative
|
||||
// wrapper, holding the XPCWrappedNative in its private slot. A slim wrapper
|
||||
// also holds a pointer to its XPCWrappedNativeProto in a reserved slot, we can
|
||||
// check that slot for a non-void value to distinguish between the two.
|
||||
|
||||
// Only use these macros if IS_WRAPPER_CLASS(obj->getClass()) is true.
|
||||
#define IS_WN_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && obj->getSlot(0).isUndefined())
|
||||
#define IS_SLIM_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && !obj->getSlot(0).isUndefined())
|
||||
|
||||
// Use these macros if IS_WRAPPER_CLASS(obj->getClass()) might be false.
|
||||
// Avoid calling them if IS_WRAPPER_CLASS(obj->getClass()) can only be
|
||||
// true, as we'd do a redundant call to IS_WRAPPER_CLASS.
|
||||
#define IS_WN_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(obj->getClass()) && IS_WN_WRAPPER_OBJECT(obj))
|
||||
#define IS_SLIM_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(obj->getClass()) && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
|
||||
inline JSObject *
|
||||
xpc_GetGlobalForObject(JSObject *obj)
|
||||
{
|
||||
while(JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
return obj;
|
||||
}
|
||||
|
||||
inline JSObject*
|
||||
xpc_GetCachedSlimWrapper(nsWrapperCache *cache, JSObject *scope, jsval *vp)
|
||||
{
|
||||
if (cache) {
|
||||
JSObject* wrapper = cache->GetWrapper();
|
||||
// FIXME: Bug 585786, the check for IS_SLIM_WRAPPER_OBJECT should go
|
||||
// away
|
||||
if (wrapper &&
|
||||
IS_SLIM_WRAPPER_OBJECT(wrapper) &&
|
||||
wrapper->getCompartment() == scope->getCompartment()) {
|
||||
*vp = OBJECT_TO_JSVAL(wrapper);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user