diff --git a/js/src/jsbuiltins.cpp b/js/src/jsbuiltins.cpp index 697659e4698..c3e507c8503 100644 --- a/js/src/jsbuiltins.cpp +++ b/js/src/jsbuiltins.cpp @@ -419,7 +419,8 @@ js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* pa closure->map = scope; closure->init(&js_FunctionClass, proto, parent, - reinterpret_cast(fun)); + reinterpret_cast(fun), + DSLOTS_NULL_INIT_CLOSURE); return closure; } JS_DEFINE_CALLINFO_4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT, OBJECT, 0, 0) diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 940507a51ba..ecb5d43b8f9 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -246,6 +246,8 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, SPROP_HAS_VALID_SLOT(sprop, scope)) { /* Great, let's cache sprop's slot and use it on cache hit. */ vword = SLOT_TO_PCVAL(sprop->slot); + if (sprop->slot >= JS_INITIAL_NSLOTS && !DSLOTS_IS_NOT_NULL(obj)) + DSLOTS_BUMP(obj); } else { /* Best we can do is to cache sprop (still a nice speedup). */ vword = SPROP_TO_PCVAL(sprop); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index ad836fa602b..d76c7a6836d 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2236,7 +2236,8 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, obj->init(clasp, proto, (!parent && proto) ? proto->getParent() : parent, - JSObject::defaultPrivate(clasp)); + JSObject::defaultPrivate(clasp), + OPS_IS_NATIVE(ops) ? DSLOTS_NULL_INIT_OBJECT_NATIVE : DSLOTS_NULL_INIT_OBJECT_NONNATIVE); if (OPS_IS_NATIVE(ops)) { if (!InitScopeForObject(cx, obj, proto, ops)) { @@ -2330,7 +2331,7 @@ NewNativeObject(JSContext* cx, JSClass* clasp, JSObject* proto, if (!obj) return NULL; - obj->init(clasp, proto, parent, privateSlotValue); + obj->init(clasp, proto, parent, privateSlotValue, DSLOTS_NULL_INIT_NATIVE); return InitScopeForObject(cx, obj, proto, &js_ObjectOps) ? obj : NULL; } @@ -3275,7 +3276,8 @@ js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, return NULL; } obj->map = scope; - obj->init(clasp, proto, proto->getParent(), privateSlotValue); + obj->init(clasp, proto, proto->getParent(), privateSlotValue, + DSLOTS_NULL_INIT_JSNATIVE); return obj; } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 9826223cd5c..92f0bb9d33a 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -233,7 +233,7 @@ struct JSObject { /* The map field is not initialized here and should be set separately. */ void init(JSClass *clasp, JSObject *proto, JSObject *parent, - jsval privateSlotValue) { + jsval privateSlotValue, jsval *nullPtr) { JS_ASSERT(((jsuword) clasp & 3) == 0); JS_STATIC_ASSERT(JSSLOT_PRIVATE + 3 == JS_INITIAL_NSLOTS); JS_ASSERT_IF(clasp->flags & JSCLASS_HAS_PRIVATE, @@ -248,7 +248,7 @@ struct JSObject { fslots[JSSLOT_PRIVATE] = privateSlotValue; fslots[JSSLOT_PRIVATE + 1] = JSVAL_VOID; fslots[JSSLOT_PRIVATE + 2] = JSVAL_VOID; - dslots = DSLOTS_NULL_INIT; + dslots = nullPtr; } JSBool lookupProperty(JSContext *cx, jsid id, diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 803c50fa77f..d9259e9ce68 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -370,17 +370,23 @@ extern JSBool js_CStringsAreUTF8; */ #define JS_ARGS_LENGTH_MAX (JS_BIT(24) - 1) -#define DSLOTS_NULL_SHIFT 8 -#define DSLOTS_NULL_RESIZE_SLOTS ((jsval*) (1 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_ARRAY_FINALIZE ((jsval*) (2 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_NEW_EMPTY_ARRAY ((jsval*) (3 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_CLONE_BLOCK_OBJECT ((jsval*) (4 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_INIT ((jsval*) (5 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_SHRINK_SLOTS ((jsval*) (6 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_SHIFT 8 +#define DSLOTS_NULL_RESIZE_SLOTS ((jsval*) (1 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_ARRAY_FINALIZE ((jsval*) (2 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_NEW_EMPTY_ARRAY ((jsval*) (3 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_CLONE_BLOCK_OBJECT ((jsval*) (4 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_SHRINK_SLOTS ((jsval*) (5 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_NULL_LIMIT (16 << DSLOTS_NULL_SHIFT) +#define DSLOTS_NULL_INIT_OBJECT_NATIVE ((jsval*) (6 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_INIT_OBJECT_NONNATIVE ((jsval*) (7 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_INIT_NATIVE ((jsval*) (8 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_INIT_JSNATIVE ((jsval*) (9 << DSLOTS_NULL_SHIFT)) +#define DSLOTS_NULL_INIT_CLOSURE ((jsval*) (10 << DSLOTS_NULL_SHIFT)) -#define DSLOTS_IS_NOT_NULL(obj) (uintptr_t(obj->dslots) >= DSLOTS_NULL_LIMIT) +#define DSLOTS_NULL_LIMIT (16 << DSLOTS_NULL_SHIFT) + +#define DSLOTS_IS_NOT_NULL(obj) (uintptr_t(obj->dslots) >= DSLOTS_NULL_LIMIT) #define DSLOTS_NORMALIZE(obj) (DSLOTS_IS_NOT_NULL(obj) ? (obj)->dslots : NULL) +#define DSLOTS_BUMP(obj) (obj->dslots = (jsval*) (uintptr_t((obj)->dslots) | (1 << (DSLOTS_NULL_SHIFT-1)))) #endif /* jsprvtd_h___ */