Allow reading reserved slots without locking if we know its safe to do so (570404, r=brendan).

This commit is contained in:
Andreas Gal
2010-06-07 21:35:58 -04:00
parent ecba331049
commit ae8d431ba1
4 changed files with 18 additions and 21 deletions

View File

@@ -1443,9 +1443,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, JSBool *resolved
return JS_TRUE; return JS_TRUE;
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(stdnm->clasp); JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(stdnm->clasp);
jsval v; jsval v = obj->getReservedSlot(key);
if (!js_GetReservedSlot(cx, obj, key, &v))
return JS_FALSE;
if (!JSVAL_IS_PRIMITIVE(v)) if (!JSVAL_IS_PRIMITIVE(v))
return JS_TRUE; return JS_TRUE;
@@ -4083,8 +4081,7 @@ js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, jsval *vp)
JSObject *tmp; JSObject *tmp;
JSFastNative native; JSFastNative native;
if (!js_GetReservedSlot(cx, JSVAL_TO_OBJECT(*vp), 0, &fsv)) fsv = JSVAL_TO_OBJECT(*vp)->getReservedSlot(0);
return JS_FALSE;
fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv); fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
JS_ASSERT((~fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == 0); JS_ASSERT((~fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == 0);
@@ -4139,8 +4136,7 @@ js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
JSFunctionSpec *fs; JSFunctionSpec *fs;
JSObject *tmp; JSObject *tmp;
if (!js_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), 0, &fsv)) fsv = JSVAL_TO_OBJECT(argv[-2])->getReservedSlot(0);
return JS_FALSE;
fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv); fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
JS_ASSERT((fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == JS_ASSERT((fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) ==
JSFUN_GENERIC_NATIVE); JSFUN_GENERIC_NATIVE);

View File

@@ -3740,15 +3740,6 @@ static JSObjectOp lazy_prototype_init[JSProto_LIMIT] = {
JS_END_EXTERN_C JS_END_EXTERN_C
static jsval
GetGlobalObjectReservedSlot(JSContext *cx, JSObject *obj, uint32 index)
{
JSClass *clasp = obj->getClass();
JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
uint32 slot = JSSLOT_START(clasp) + index;
return (slot < obj->numSlots()) ? obj->getSlot(slot) : JSVAL_VOID;
}
JSBool JSBool
js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
JSObject **objp) JSObject **objp)
@@ -3767,7 +3758,7 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
return JS_TRUE; return JS_TRUE;
} }
v = GetGlobalObjectReservedSlot(cx, obj, key); v = obj->getReservedSlot(key);
if (!JSVAL_IS_PRIMITIVE(v)) { if (!JSVAL_IS_PRIMITIVE(v)) {
*objp = JSVAL_TO_OBJECT(v); *objp = JSVAL_TO_OBJECT(v);
return JS_TRUE; return JS_TRUE;
@@ -3791,7 +3782,7 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
if (!init(cx, obj)) { if (!init(cx, obj)) {
ok = JS_FALSE; ok = JS_FALSE;
} else { } else {
v = GetGlobalObjectReservedSlot(cx, obj, key); v = obj->getReservedSlot(key);
if (!JSVAL_IS_PRIMITIVE(v)) if (!JSVAL_IS_PRIMITIVE(v))
cobj = JSVAL_TO_OBJECT(v); cobj = JSVAL_TO_OBJECT(v);
} }
@@ -5752,7 +5743,7 @@ js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
} }
scope = scope->getGlobal(); scope = scope->getGlobal();
if (scope->getClass()->flags & JSCLASS_IS_GLOBAL) { if (scope->getClass()->flags & JSCLASS_IS_GLOBAL) {
jsval v = GetGlobalObjectReservedSlot(cx, scope, JSProto_LIMIT + protoKey); jsval v = scope->getReservedSlot(JSProto_LIMIT + protoKey);
if (!JSVAL_IS_PRIMITIVE(v)) { if (!JSVAL_IS_PRIMITIVE(v)) {
*protop = JSVAL_TO_OBJECT(v); *protop = JSVAL_TO_OBJECT(v);
return true; return true;
@@ -6326,7 +6317,8 @@ js_ReportGetterOnlyAssignment(JSContext *cx)
JSCompartment * JSCompartment *
JSObject::getCompartment(JSContext *cx) { JSObject::getCompartment(JSContext *cx) {
JSObject *obj = getGlobal(); JSObject *obj = getGlobal();
jsval v = GetGlobalObjectReservedSlot(cx, obj, JSRESERVED_GLOBAL_COMPARTMENT); JS_ASSERT(obj->getClass()->flags & JSCLASS_IS_GLOBAL);
jsval v = obj->getReservedSlot(JSRESERVED_GLOBAL_COMPARTMENT);
return (JSCompartment *) JSVAL_TO_PRIVATE(v); return (JSCompartment *) JSVAL_TO_PRIVATE(v);
} }

View File

@@ -348,6 +348,8 @@ struct JSObject {
inline jsval getSlotMT(JSContext *cx, uintN slot); inline jsval getSlotMT(JSContext *cx, uintN slot);
inline void setSlotMT(JSContext *cx, uintN slot, jsval value); inline void setSlotMT(JSContext *cx, uintN slot, jsval value);
inline jsval getReservedSlot(uintN index) const;
JSObject *getProto() const { JSObject *getProto() const {
return JSVAL_TO_OBJECT(fslots[JSSLOT_PROTO]); return JSVAL_TO_OBJECT(fslots[JSSLOT_PROTO]);
} }
@@ -1285,7 +1287,7 @@ js_Clear(JSContext *cx, JSObject *obj);
extern bool extern bool
js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp);
bool extern bool
js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v); js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v);
/* /*

View File

@@ -97,6 +97,13 @@ JSObject::setSlotMT(JSContext *cx, uintN slot, jsval value)
#endif #endif
} }
inline jsval
JSObject::getReservedSlot(uintN index) const
{
uint32 slot = JSSLOT_START(getClass()) + index;
return (slot < numSlots()) ? getSlot(slot) : JSVAL_VOID;
}
inline bool inline bool
JSObject::isPrimitive() const JSObject::isPrimitive() const
{ {