Bug 558144 - un-macroize OBJ_SCOPE, OBJ_SHAPE, LOCKED_OBJ_SET_SLOT, LOCKED_OBJ_GET_SLOT (r=Waldo)

This commit is contained in:
Luke Wagner 2010-04-08 11:22:04 -07:00
parent e94e8073c1
commit 515c38eb66
24 changed files with 237 additions and 213 deletions

View File

@ -1471,7 +1471,7 @@ static JSBool
AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom)
{
JS_LOCK_OBJ(cx, obj);
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
bool found = scope->hasProperty(ATOM_TO_JSID(atom));
JS_UNLOCK_SCOPE(cx, scope);
return found;
@ -2766,13 +2766,13 @@ JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep)
return JS_FALSE;
}
scope = OBJ_SCOPE(obj);
scope = obj->scope();
#if defined JS_THREADSAFE && defined DEBUG
/* Insist on scope being used exclusively by cx's thread. */
if (scope->title.ownercx != cx) {
JS_LOCK_OBJ(cx, obj);
JS_ASSERT(OBJ_SCOPE(obj) == scope);
JS_ASSERT(obj->scope() == scope);
JS_ASSERT(scope->title.ownercx == cx);
JS_UNLOCK_SCOPE(cx, scope);
}
@ -3073,12 +3073,12 @@ LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop,
AutoScopePropertyRooter root(cx, sprop);
JS_UNLOCK_OBJ(cx, obj2);
*vp = sprop->methodValue();
return OBJ_SCOPE(obj2)->methodReadBarrier(cx, sprop, vp);
return obj2->scope()->methodReadBarrier(cx, sprop, vp);
}
/* Peek at the native property's slot value, without doing a Get. */
*vp = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
*vp = SPROP_HAS_VALID_SLOT(sprop, obj2->scope())
? obj2->lockedGetSlot(sprop->slot)
: JSVAL_TRUE;
} else if (obj2->isDenseArray()) {
ok = js_GetDenseArrayElementValue(cx, obj2, prop, vp);
@ -3121,8 +3121,8 @@ GetPropertyAttributesById(JSContext *cx, JSObject *obj, jsid id, uintN flags,
desc->getter = sprop->getter();
desc->setter = sprop->setter();
desc->value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
desc->value = SPROP_HAS_VALID_SLOT(sprop, obj2->scope())
? obj2->lockedGetSlot(sprop->slot)
: JSVAL_VOID;
} else {
desc->getter = NULL;
@ -3262,7 +3262,7 @@ AlreadyHasOwnPropertyHelper(JSContext *cx, JSObject *obj, jsid id,
}
JS_LOCK_OBJ(cx, obj);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
*foundp = scope->hasProperty(id);
JS_UNLOCK_SCOPE(cx, scope);
return JS_TRUE;
@ -3950,7 +3950,7 @@ JS_NewPropertyIterator(JSContext *cx, JSObject *obj)
if (obj->isNative()) {
/* Native case: start with the last property in obj's own scope. */
scope = OBJ_SCOPE(obj);
scope = obj->scope();
pdata = scope->lastProperty();
index = -1;
} else {
@ -3989,7 +3989,7 @@ JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp)
/* Native case: private data is a property tree node pointer. */
obj = iterobj->getParent();
JS_ASSERT(obj->isNative());
scope = OBJ_SCOPE(obj);
scope = obj->scope();
sprop = (JSScopeProperty *) iterobj->getPrivate();
/*

View File

@ -891,7 +891,7 @@ js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
*/
if (!obj->isNative())
return JS_TRUE;
if (OBJ_SCOPE(obj)->hadIndexedProperties())
if (obj->scope()->hadIndexedProperties())
return JS_TRUE;
}
return JS_FALSE;
@ -1303,7 +1303,7 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj)
} else {
/* arrayProto is Array.prototype. */
JS_ASSERT(arrayProto->getClass() == &js_SlowArrayClass);
emptyShape = OBJ_SCOPE(arrayProto)->emptyScope->shape;
emptyShape = arrayProto->scope()->emptyScope->shape;
}
JSScope *scope = JSScope::create(cx, &js_SlowArrayObjectOps, &js_SlowArrayClass, obj,
emptyShape);

View File

@ -204,7 +204,7 @@ js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop)
JS_LOCK_OBJ(cx, obj);
uint32 slot = sprop->slot;
JSScope* scope = OBJ_SCOPE(obj);
JSScope* scope = obj->scope();
if (slot != scope->freeslot)
goto exit_trace;
JS_ASSERT(sprop->parent == scope->lastProperty());

View File

@ -465,7 +465,7 @@ DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag)
DBG_UNLOCK(cx->runtime);
if (!setter) {
JS_LOCK_OBJ(cx, wp->object);
scope = OBJ_SCOPE(wp->object);
scope = wp->object->scope();
/*
* If the property wasn't found on wp->object, or it isn't still being
@ -555,7 +555,7 @@ FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if (OBJ_SCOPE(wp->object) == scope && wp->sprop->id == id)
if (wp->object->scope() == scope && wp->sprop->id == id)
return wp;
}
return NULL;
@ -591,7 +591,7 @@ js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
for (wp = (JSWatchPoint *)rt->watchPointList.next;
&wp->links != &rt->watchPointList;
wp = (JSWatchPoint *)wp->links.next) {
if ((!scope || OBJ_SCOPE(wp->object) == scope) && wp->sprop == sprop) {
if ((!scope || wp->object->scope() == scope) && wp->sprop == sprop) {
setter = wp->setter;
break;
}
@ -625,7 +625,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
JS_LOCK_OBJ(cx, obj);
propid = ID_TO_VALUE(sprop->id);
userid = SPROP_USERID(sprop);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
JS_UNLOCK_OBJ(cx, obj);
/* NB: wp is held, so we can safely dereference it still. */
@ -858,7 +858,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
rt = cx->runtime;
if (!sprop) {
/* Check for a deleted symbol watchpoint, which holds its property. */
sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
sprop = js_FindWatchPoint(rt, obj->scope(), propid);
if (!sprop) {
/* Make a new property in obj so we can watch for the first set. */
if (!js_DefineNativeProperty(cx, obj, propid, JSVAL_VOID, NULL, NULL,
@ -875,8 +875,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
intN shortid;
if (pobj->isNative()) {
value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))
? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
value = SPROP_HAS_VALID_SLOT(sprop, pobj->scope())
? pobj->lockedGetSlot(sprop->slot)
: JSVAL_VOID;
getter = sprop->getter();
setter = sprop->setter();
@ -909,7 +909,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
*/
ok = JS_TRUE;
DBG_LOCK(rt);
wp = FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
wp = FindWatchPoint(rt, obj->scope(), propid);
if (!wp) {
DBG_UNLOCK(rt);
watcher = js_WrapWatchedSetter(cx, propid, sprop->attributes(), sprop->setter());
@ -949,7 +949,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
* a watchpoint for (obj, propid).
*/
DBG_LOCK(rt);
JS_ASSERT(!FindWatchPoint(rt, OBJ_SCOPE(obj), propid));
JS_ASSERT(!FindWatchPoint(rt, obj->scope(), propid));
JS_APPEND_LINK(&wp->links, &rt->watchPointList);
++rt->debuggerMutations;
}
@ -1429,7 +1429,7 @@ JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
JSScope *scope;
sprop = *iteratorp;
scope = OBJ_SCOPE(obj);
scope = obj->scope();
/* XXXbe minor(?) incompatibility: iterate in reverse definition order */
sprop = sprop ? sprop->parent : scope->lastProperty();
@ -1478,7 +1478,7 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
}
pd->alias = JSVAL_VOID;
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
JSScopeProperty *aprop;
for (aprop = scope->lastProperty(); aprop; aprop = aprop->parent) {
@ -1510,7 +1510,7 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
return JS_FALSE;
/* have no props, or object's scope has not mutated from that of proto */
scope = OBJ_SCOPE(obj);
scope = obj->scope();
if (scope->entryCount == 0) {
pda->length = 0;
pda->array = NULL;
@ -1655,7 +1655,7 @@ JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
* sizeof obj->dslots[0];
}
if (obj->isNative()) {
scope = OBJ_SCOPE(obj);
scope = obj->scope();
if (!scope->isSharedEmpty()) {
nbytes += sizeof *scope;
nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);

View File

@ -1589,7 +1589,7 @@ js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSStmtInfo *stmt
obj = stmt->blockObj;
JS_ASSERT(obj->getClass() == &js_BlockClass);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
sprop = scope->lookup(ATOM_TO_JSID(atom));
if (sprop) {
JS_ASSERT(sprop->hasShortID());
@ -1880,7 +1880,7 @@ EmitEnterBlock(JSContext *cx, JSParseNode *pn, JSCodeGenerator *cg)
#endif
}
OBJ_SCOPE(blockObj)->freeslot = JSSLOT_FREE(&js_BlockClass);
blockObj->scope()->freeslot = JSSLOT_FREE(&js_BlockClass);
return js_GrowSlots(cx, blockObj, JSSLOT_FREE(&js_BlockClass));
}

View File

@ -2539,7 +2539,7 @@ FinalizeObject(JSContext *cx, JSObject *obj, unsigned thingKind)
#endif
if (JS_LIKELY(obj->isNative())) {
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (scope->isSharedEmpty())
static_cast<JSEmptyScope *>(scope)->dropFromGC(cx);
else

View File

@ -2158,7 +2158,7 @@ AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, JSFrameRegs& regs,
}
if (!ok)
return false;
if (cx->runtime->gcNumber != sample || entry->vshape() != OBJ_SHAPE(pobj)) {
if (cx->runtime->gcNumber != sample || entry->vshape() != pobj->shape()) {
pobj->dropProperty(cx, prop);
return true;
}
@ -2172,15 +2172,15 @@ AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, JSFrameRegs& regs,
} else if (entry->vword.isSprop()) {
JS_ASSERT(entry->vword.toSprop() == sprop);
JS_ASSERT_IF(sprop->isMethod(),
sprop->methodValue() == LOCKED_OBJ_GET_SLOT(pobj, sprop->slot));
sprop->methodValue() == pobj->lockedGetSlot(sprop->slot));
} else {
jsval v;
JS_ASSERT(entry->vword.isObject());
JS_ASSERT(!entry->vword.isNull());
JS_ASSERT(OBJ_SCOPE(pobj)->brandedOrHasMethodBarrier());
JS_ASSERT(pobj->scope()->brandedOrHasMethodBarrier());
JS_ASSERT(sprop->hasDefaultGetterOrIsMethod());
JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
v = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, pobj->scope()));
v = pobj->lockedGetSlot(sprop->slot);
JS_ASSERT(VALUE_IS_FUNCTION(cx, v));
JS_ASSERT(entry->vword.toObject() == JSVAL_TO_OBJECT(v));

View File

@ -690,7 +690,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
* Native object locking is inlined here to optimize the single-threaded
* and contention-free multi-threaded cases.
*/
scope = OBJ_SCOPE(obj);
scope = obj->scope();
title = &scope->title;
JS_ASSERT(title->ownercx != cx);
JS_ASSERT(slot < scope->freeslot);
@ -718,7 +718,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
* require either a restart from the top of this routine, or a thin
* lock release followed by fat lock acquisition.
*/
if (scope == OBJ_SCOPE(obj)) {
if (scope == obj->scope()) {
v = obj->getSlot(slot);
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
/* Assert that scope locks never revert to flyweight. */
@ -749,7 +749,7 @@ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
* object's scope (whose lock was not flyweight, else we wouldn't be here
* in the first place!).
*/
title = &OBJ_SCOPE(obj)->title;
title = &obj->scope()->title;
if (title->ownercx != cx)
js_UnlockTitle(cx, title);
return v;
@ -778,7 +778,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
* Native object locking is inlined here to optimize the single-threaded
* and contention-free multi-threaded cases.
*/
scope = OBJ_SCOPE(obj);
scope = obj->scope();
title = &scope->title;
JS_ASSERT(title->ownercx != cx);
JS_ASSERT(slot < scope->freeslot);
@ -792,7 +792,7 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
if (CX_THREAD_IS_RUNNING_GC(cx) ||
scope->sealed() ||
(title->ownercx && ClaimTitle(title, cx))) {
LOCKED_OBJ_SET_SLOT(obj, slot, v);
obj->lockedSetSlot(slot, v);
return;
}
@ -801,8 +801,8 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
me = CX_THINLOCK_ID(cx);
JS_ASSERT(CURRENT_THREAD_IS_ME(me));
if (NativeCompareAndSwap(&tl->owner, 0, me)) {
if (scope == OBJ_SCOPE(obj)) {
LOCKED_OBJ_SET_SLOT(obj, slot, v);
if (scope == obj->scope()) {
obj->lockedSetSlot(slot, v);
if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
/* Assert that scope locks never revert to flyweight. */
JS_ASSERT(title->ownercx != cx);
@ -815,18 +815,18 @@ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
if (!NativeCompareAndSwap(&tl->owner, me, 0))
js_Dequeue(tl);
} else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
LOCKED_OBJ_SET_SLOT(obj, slot, v);
obj->lockedSetSlot(slot, v);
return;
}
#endif
js_LockObj(cx, obj);
LOCKED_OBJ_SET_SLOT(obj, slot, v);
obj->lockedSetSlot(slot, v);
/*
* Same drill as above, in js_GetSlotThreadSafe.
*/
title = &OBJ_SCOPE(obj)->title;
title = &obj->scope()->title;
if (title->ownercx != cx)
js_UnlockTitle(cx, title);
}
@ -1321,7 +1321,7 @@ js_LockObj(JSContext *cx, JSObject *obj)
return;
for (;;) {
scope = OBJ_SCOPE(obj);
scope = obj->scope();
title = &scope->title;
if (scope->sealed() && !cx->lockedSealedTitle) {
cx->lockedSealedTitle = title;
@ -1331,7 +1331,7 @@ js_LockObj(JSContext *cx, JSObject *obj)
js_LockTitle(cx, title);
/* If obj still has this scope, we're done. */
if (scope == OBJ_SCOPE(obj))
if (scope == obj->scope())
return;
/* Lost a race with a mutator; retry with obj's new scope. */
@ -1343,7 +1343,7 @@ void
js_UnlockObj(JSContext *cx, JSObject *obj)
{
JS_ASSERT(obj->isNative());
js_UnlockTitle(cx, &OBJ_SCOPE(obj)->title);
js_UnlockTitle(cx, &obj->scope()->title);
}
void
@ -1392,7 +1392,7 @@ js_IsRuntimeLocked(JSRuntime *rt)
JSBool
js_IsObjLocked(JSContext *cx, JSObject *obj)
{
return js_IsTitleLocked(cx, &OBJ_SCOPE(obj)->title);
return js_IsTitleLocked(cx, &obj->scope()->title);
}
JSBool

View File

@ -134,7 +134,7 @@ struct JSTitle {
#ifdef JS_DEBUG_TITLE_LOCKS
#define JS_SET_OBJ_INFO(obj_, file_, line_) \
JS_SET_SCOPE_INFO(OBJ_SCOPE(obj_), file_, line_)
JS_SET_SCOPE_INFO((obj_)->scope(), file_, line_)
#define JS_SET_SCOPE_INFO(scope_, file_, line_) \
js_SetScopeInfo(scope_, file_, line_)
@ -156,12 +156,21 @@ struct JSTitle {
*/
#define CX_OWNS_SCOPE_TITLE(cx,scope) ((scope)->title.ownercx == (cx))
#define JS_LOCK_OBJ(cx,obj) (CX_OWNS_SCOPE_TITLE(cx, OBJ_SCOPE(obj)) \
? (void)0 \
: (js_LockObj(cx, obj), \
JS_SET_OBJ_INFO(obj,__FILE__,__LINE__)))
#define JS_UNLOCK_OBJ(cx,obj) (CX_OWNS_SCOPE_TITLE(cx, OBJ_SCOPE(obj)) \
? (void)0 : js_UnlockObj(cx, obj))
#define JS_LOCK_OBJ(cx,obj) \
JS_BEGIN_MACRO \
JSObject *obj_ = (obj); \
if (!CX_OWNS_SCOPE_TITLE(cx, obj_->scope())) { \
js_LockObj(cx, obj_); \
JS_SET_OBJ_INFO(obj_, __FILE__, __LINE__); \
} \
JS_END_MACRO
#define JS_UNLOCK_OBJ(cx,obj) \
JS_BEGIN_MACRO \
JSObject *obj_ = (obj); \
if (!CX_OWNS_SCOPE_TITLE(cx, obj_->scope())) \
js_UnlockObj(cx, obj_); \
JS_END_MACRO
#define JS_LOCK_TITLE(cx,title) \
((title)->ownercx == (cx) ? (void)0 \
@ -282,7 +291,7 @@ extern void js_SetScopeInfo(JSScope *scope, const char *file, int line);
JS_NO_TIMEOUT)
#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone)
#define CX_OWNS_OBJECT_TITLE(cx,obj) CX_OWNS_SCOPE_TITLE(cx, OBJ_SCOPE(obj))
#define CX_OWNS_OBJECT_TITLE(cx,obj) CX_OWNS_SCOPE_TITLE(cx, (obj)->scope())
#ifndef JS_SET_OBJ_INFO
#define JS_SET_OBJ_INFO(obj,f,l) ((void)0)

View File

@ -265,7 +265,7 @@ js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
JSObject *oldproto = obj;
while (oldproto && oldproto->isNative()) {
JS_LOCK_OBJ(cx, oldproto);
JSScope *scope = OBJ_SCOPE(oldproto);
JSScope *scope = oldproto->scope();
scope->protoShapeChange(cx);
JSObject *tmp = oldproto->getProto();
JS_UNLOCK_OBJ(cx, oldproto);
@ -2245,7 +2245,7 @@ DefinePropertyObject(JSContext *cx, JSObject *obj, const PropertyDescriptor &des
JS_ASSERT(obj->map->ops->defineProperty == js_DefineProperty);
/* 8.12.9 steps 2-4. */
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (!current) {
if (scope->sealed())
return Reject(cx, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
@ -2785,7 +2785,7 @@ InitScopeForObject(JSContext* cx, JSObject* obj, JSObject* proto, JSObjectOps* o
if (proto && proto->isNative()) {
JS_LOCK_OBJ(cx, proto);
scope = OBJ_SCOPE(proto);
scope = proto->scope();
if (scope->canProvideEmptyScope(ops, clasp)) {
JSScope *emptyScope = scope->getEmptyScope(cx, clasp);
JS_UNLOCK_SCOPE(cx, scope);
@ -3026,7 +3026,7 @@ js_NewInstance(JSContext *cx, JSClass *clasp, JSObject *ctor)
JSAtom *atom = cx->runtime->atomState.classPrototypeAtom;
JSScope *scope = OBJ_SCOPE(ctor);
JSScope *scope = ctor->scope();
#ifdef JS_THREADSAFE
if (scope->title.ownercx != cx)
return NULL;
@ -3380,10 +3380,10 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
/*
* Block objects should never be exposed to scripts. Thus the clone should
* not own the property map and rather always share it with the prototype
* object. This allows us to skip updating OBJ_SCOPE(obj)->freeslot after
* object. This allows us to skip updating obj->scope()->freeslot after
* we copy the stack slots into reserved slots.
*/
JS_ASSERT(OBJ_SCOPE(obj)->object != obj);
JS_ASSERT(obj->scope()->object != obj);
/* Block objects should not have reserved slots before they are put. */
JS_ASSERT(obj->numSlots() == JS_INITIAL_NSLOTS);
@ -3582,7 +3582,7 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
/* Find a property to XDR. */
do {
/* If sprop is NULL, this is the first property. */
sprop = sprop ? sprop->parent : OBJ_SCOPE(obj)->lastProperty();
sprop = sprop ? sprop->parent : obj->scope()->lastProperty();
} while (!sprop->hasShortID());
JS_ASSERT(sprop->getter() == block_getProperty);
@ -3769,7 +3769,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
*
* All callers of JSObject::initSharingEmptyScope depend on this.
*/
if (!OBJ_SCOPE(proto)->ensureEmptyScope(cx, clasp))
if (!proto->scope()->ensureEmptyScope(cx, clasp))
goto bad;
/* If this is a standard class, cache its prototype. */
@ -3903,7 +3903,7 @@ js_EnsureReservedSlots(JSContext *cx, JSObject *obj, size_t nreserved)
if (nslots > obj->numSlots() && !AllocSlots(cx, obj, nslots))
return false;
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (!scope->isSharedEmpty()) {
#ifdef JS_THREADSAFE
JS_ASSERT(scope->title.ownercx->thread == cx->thread);
@ -4065,8 +4065,8 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
if (prop) {
if (pobj->isNative()) {
sprop = (JSScopeProperty *) prop;
if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))) {
v = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
if (SPROP_HAS_VALID_SLOT(sprop, pobj->scope())) {
v = pobj->lockedGetSlot(sprop->slot);
if (JSVAL_IS_PRIMITIVE(v))
v = JSVAL_VOID;
}
@ -4150,7 +4150,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
JSBool
js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp)
{
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
JS_ASSERT(scope->object == obj);
JSClass *clasp = obj->getClass();
@ -4173,9 +4173,9 @@ js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp)
void
js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
{
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
JS_ASSERT(scope->object == obj);
LOCKED_OBJ_SET_SLOT(obj, slot, JSVAL_VOID);
obj->lockedSetSlot(slot, JSVAL_VOID);
if (scope->freeslot == slot + 1)
scope->freeslot = slot;
}
@ -4257,7 +4257,7 @@ PurgeProtoChain(JSContext *cx, JSObject *obj, jsid id)
continue;
}
JS_LOCK_OBJ(cx, obj);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
sprop = scope->lookup(id);
if (sprop) {
PCMETER(JS_PROPERTY_CACHE(cx).pcpurges++);
@ -4373,7 +4373,7 @@ AddPropertyHelper(JSContext *cx, JSClass *clasp, JSObject *obj, JSScope *scope,
return false;
if (*vp != nominal) {
if (SPROP_HAS_VALID_SLOT(sprop, scope))
LOCKED_OBJ_SET_SLOT(obj, sprop->slot, *vp);
obj->lockedSetSlot(sprop->slot, *vp);
}
}
return true;
@ -4419,14 +4419,14 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
return JS_FALSE;
sprop = (JSScopeProperty *) prop;
if (sprop && pobj == obj && sprop->isAccessorDescriptor()) {
sprop = OBJ_SCOPE(obj)->changeProperty(cx, sprop, attrs,
JSPROP_GETTER | JSPROP_SETTER,
(attrs & JSPROP_GETTER)
? getter
: sprop->getter(),
(attrs & JSPROP_SETTER)
? setter
: sprop->setter());
sprop = obj->scope()->changeProperty(cx, sprop, attrs,
JSPROP_GETTER | JSPROP_SETTER,
(attrs & JSPROP_GETTER)
? getter
: sprop->getter(),
(attrs & JSPROP_SETTER)
? setter
: sprop->setter());
/* NB: obj == pobj, so we can share unlock code at the bottom. */
if (!sprop)
@ -4501,7 +4501,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
/* Store value before calling addProperty, in case the latter GC's. */
if (SPROP_HAS_VALID_SLOT(sprop, scope))
LOCKED_OBJ_SET_SLOT(obj, sprop->slot, value);
obj->lockedSetSlot(sprop->slot, value);
/* XXXbe called with lock held */
if (!AddPropertyHelper(cx, clasp, obj, scope, sprop, &value)) {
@ -4560,7 +4560,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
start = obj;
for (protoIndex = 0; ; protoIndex++) {
JS_LOCK_OBJ(cx, obj);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
sprop = scope->lookup(id);
/* Try obj's class resolve hook if id was not found in obj's scope. */
@ -4638,12 +4638,12 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
* not on obj's proto chain. That last case is a
* "too bad!" case.
*/
scope = OBJ_SCOPE(obj2);
scope = obj2->scope();
if (!scope->isSharedEmpty())
sprop = scope->lookup(id);
}
if (sprop) {
JS_ASSERT(scope == OBJ_SCOPE(obj2));
JS_ASSERT(scope == obj2->scope());
JS_ASSERT(!scope->isSharedEmpty());
obj = obj2;
} else if (obj2 != obj) {
@ -4663,7 +4663,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
goto cleanup;
JS_LOCK_OBJ(cx, obj);
JS_ASSERT(obj->isNative());
scope = OBJ_SCOPE(obj);
scope = obj->scope();
if (!scope->isSharedEmpty())
sprop = scope->lookup(id);
}
@ -4679,7 +4679,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
if (sprop) {
SCOPE_DEPTH_ACCUM(&cx->runtime->protoLookupDepthStats, protoIndex);
JS_ASSERT(OBJ_SCOPE(obj) == scope);
JS_ASSERT(obj->scope() == scope);
*objp = obj;
*propp = (JSProperty *) sprop;
@ -4706,7 +4706,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
* be on the prototype chain of other objects.
*/
JS_ASSERT_IF(obj->getClass() != &js_BlockClass,
OBJ_SCOPE(obj) != OBJ_SCOPE(proto));
obj->scope() != proto->scope());
obj = proto;
}
@ -4896,11 +4896,11 @@ js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
JS_ASSERT(pobj->isNative());
JS_ASSERT(JS_IS_OBJ_LOCKED(cx, pobj));
scope = OBJ_SCOPE(pobj);
scope = pobj->scope();
slot = sprop->slot;
*vp = (slot != SPROP_INVALID_SLOT)
? LOCKED_OBJ_GET_SLOT(pobj, slot)
? pobj->lockedGetSlot(slot)
: JSVAL_VOID;
if (sprop->hasDefaultGetter())
return true;
@ -4928,7 +4928,7 @@ js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
JS_UNLOCK_SCOPE(cx, scope);
return false;
}
LOCKED_OBJ_SET_SLOT(pobj, slot, v);
pobj->lockedSetSlot(slot, v);
}
return true;
@ -4946,7 +4946,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added,
JS_ASSERT(obj->isNative());
JS_ASSERT(JS_IS_OBJ_LOCKED(cx, obj));
scope = OBJ_SCOPE(obj);
scope = obj->scope();
slot = sprop->slot;
if (slot != SPROP_INVALID_SLOT) {
@ -4958,7 +4958,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added,
JS_UNLOCK_SCOPE(cx, scope);
return false;
}
LOCKED_OBJ_SET_SLOT(obj, slot, *vp);
obj->lockedSetSlot(slot, *vp);
return true;
}
} else {
@ -4989,7 +4989,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added,
JS_UNLOCK_SCOPE(cx, scope);
return false;
}
LOCKED_OBJ_SET_SLOT(obj, slot, v);
obj->lockedSetSlot(slot, v);
}
return true;
@ -5188,10 +5188,10 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
id = js_CheckForStringIndex(id);
/*
* We peek at OBJ_SCOPE(obj) without locking obj. Any race means a failure
* We peek at obj->scope() without locking obj. Any race means a failure
* to seal before sharing, which is inherently ambiguous.
*/
if (OBJ_SCOPE(obj)->sealed() && OBJ_SCOPE(obj)->object == obj)
if (obj->scope()->sealed() && obj->scope()->object == obj)
return ReportReadOnly(cx, id, JSREPORT_ERROR);
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
@ -5233,7 +5233,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
* we know pobj owns it (i.e., scope->object == pobj). Therefore we
* optimize JS_UNLOCK_OBJ(cx, pobj) into JS_UNLOCK_SCOPE(cx, scope).
*/
scope = OBJ_SCOPE(pobj);
scope = pobj->scope();
/* ES5 8.12.4 [[Put]] step 2. */
if (sprop->isAccessorDescriptor()) {
@ -5373,7 +5373,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
* in js_DefineNativeProperty.
*/
if (SPROP_HAS_VALID_SLOT(sprop, scope))
LOCKED_OBJ_SET_SLOT(obj, sprop->slot, JSVAL_VOID);
obj->lockedSetSlot(sprop->slot, JSVAL_VOID);
/* XXXbe called with obj locked */
if (!AddPropertyHelper(cx, clasp, obj, scope, sprop, vp)) {
@ -5513,9 +5513,9 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
return JS_FALSE;
}
scope = OBJ_SCOPE(obj);
scope = obj->scope();
if (SPROP_HAS_VALID_SLOT(sprop, scope))
GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot));
GC_POKE(cx, obj->lockedGetSlot(sprop->slot));
ok = scope->removeProperty(cx, id);
obj->dropProperty(cx, prop);
@ -5540,7 +5540,7 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
jsid toStringId = ATOM_TO_JSID(cx->runtime->atomState.toStringAtom);
JS_LOCK_OBJ(cx, obj);
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
JSScopeProperty *sprop = scope->lookup(toStringId);
JSObject *pobj = obj;
@ -5550,13 +5550,13 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
if (pobj && pobj->getClass() == &js_StringClass) {
JS_UNLOCK_SCOPE(cx, scope);
JS_LOCK_OBJ(cx, pobj);
scope = OBJ_SCOPE(pobj);
scope = pobj->scope();
sprop = scope->lookup(toStringId);
}
}
if (sprop && sprop->hasDefaultGetter() && SPROP_HAS_VALID_SLOT(sprop, scope)) {
jsval fval = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
jsval fval = pobj->lockedGetSlot(sprop->slot);
if (VALUE_IS_FUNCTION(cx, fval)) {
JSObject *funobj = JSVAL_TO_OBJECT(fval);
@ -5719,7 +5719,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
JSNativeEnumerator *ne;
uint32 length;
do {
uint32 shape = OBJ_SHAPE(obj);
uint32 shape = obj->shape();
ENUM_CACHE_METER(nativeEnumProbes);
jsuword *cachep = &JS_THREAD_DATA(cx)->
@ -5748,7 +5748,7 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
JS_LOCK_OBJ(cx, obj);
/* Count all enumerable properties in object's scope. */
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
length = 0;
for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {
if (sprop->enumerable() && !sprop->isAlias())
@ -5938,8 +5938,8 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
sprop = (JSScopeProperty *)prop;
*attrsp = sprop->attributes();
if (!writing) {
*vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)))
? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
*vp = (SPROP_HAS_VALID_SLOT(sprop, pobj->scope()))
? pobj->lockedGetSlot(sprop->slot)
: JSVAL_VOID;
}
pobj->dropProperty(cx, prop);
@ -6518,7 +6518,7 @@ js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize)
JSScopeProperty *sprop;
if (obj->isNative()) {
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
sprop = scope->lastProperty();
while (sprop && sprop->slot != slot)
sprop = sprop->parent;
@ -6560,7 +6560,7 @@ js_TraceObject(JSTracer *trc, JSObject *obj)
JS_ASSERT(obj->isNative());
JSContext *cx = trc->context;
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (!scope->isSharedEmpty() && IS_GC_MARKING_TRACER(trc)) {
/*
* Check whether we should shrink the object's slots. Skip this check
@ -6627,7 +6627,7 @@ js_Clear(JSContext *cx, JSObject *obj)
* NB: we do not clear any reserved slots lying below JSSLOT_FREE(clasp).
*/
JS_LOCK_OBJ(cx, obj);
scope = OBJ_SCOPE(obj);
scope = obj->scope();
if (!scope->isSharedEmpty()) {
/* Now that we're done using scope->lastProp/table, clear scope. */
scope->clear(cx);
@ -6720,7 +6720,7 @@ js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)
* their own scopes before mutating, and elsewhere (e.g. js_TraceObject) we
* use obj->numSlots() rather than rely on freeslot.
*/
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (!scope->isSharedEmpty() && slot >= scope->freeslot)
scope->freeslot = slot + 1;
@ -6950,7 +6950,7 @@ js_DumpObject(JSObject *obj)
}
if (obj->isNative()) {
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (scope->sealed())
fprintf(stderr, "sealed\n");
@ -6980,8 +6980,8 @@ js_DumpObject(JSObject *obj)
fprintf(stderr, "slots:\n");
reservedEnd = i + JSCLASS_RESERVED_SLOTS(clasp);
slots = (obj->isNative() && !OBJ_SCOPE(obj)->isSharedEmpty())
? OBJ_SCOPE(obj)->freeslot
slots = (obj->isNative() && !obj->scope()->isSharedEmpty())
? obj->scope()->freeslot
: obj->numSlots();
for (; i < slots; i++) {
fprintf(stderr, " %3d ", i);

View File

@ -269,6 +269,9 @@ struct JSObject {
return clasp == getClass();
}
inline JSScope *scope() const;
inline uint32 shape() const;
bool isDelegate() const {
return (classword & jsuword(1)) != jsuword(0);
}
@ -317,6 +320,9 @@ struct JSObject {
}
}
inline jsval lockedGetSlot(uintN slot) const;
inline void lockedSetSlot(uintN slot, jsval value);
/*
* These ones are for multi-threaded ("MT") objects. Use getSlot(),
* getSlotRef(), setSlot() to directly manipulate slots in obj when only
@ -536,12 +542,7 @@ struct JSObject {
#define MAX_DSLOTS_LENGTH32 (~uint32(0) / sizeof(jsval) - 1)
#define OBJ_CHECK_SLOT(obj,slot) \
(JS_ASSERT(obj->isNative()), JS_ASSERT(slot < OBJ_SCOPE(obj)->freeslot))
#define LOCKED_OBJ_GET_SLOT(obj,slot) \
(OBJ_CHECK_SLOT(obj, slot), obj->getSlot(slot))
#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \
(OBJ_CHECK_SLOT(obj, slot), obj->setSlot(slot, value))
(JS_ASSERT((obj)->isNative()), JS_ASSERT(slot < (obj)->scope()->freeslot))
#ifdef JS_THREADSAFE
@ -617,7 +618,7 @@ extern JSBool
js_DefineBlockVariable(JSContext *cx, JSObject *obj, jsid id, intN index);
#define OBJ_BLOCK_COUNT(cx,obj) \
(OBJ_SCOPE(OBJ_IS_CLONED_BLOCK(obj) ? obj->getProto() : obj)->entryCount)
((OBJ_IS_CLONED_BLOCK(obj) ? obj->getProto() : obj)->scope()->entryCount)
#define OBJ_BLOCK_DEPTH(cx,obj) \
JSVAL_TO_INT(obj->getSlot(JSSLOT_BLOCK_DEPTH))
#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \

View File

@ -51,18 +51,18 @@ JSObject::getSlotMT(JSContext *cx, uintN slot)
/*
* If thread-safe, define a getSlotMT() that bypasses, for a native
* object, the lock-free "fast path" test of
* (OBJ_SCOPE(obj)->ownercx == cx), to avoid needlessly switching from
* (obj->scope()->ownercx == cx), to avoid needlessly switching from
* lock-free to lock-full scope when doing GC on a different context
* from the last one to own the scope. The caller in this case is
* probably a JSClass.mark function, e.g., fun_mark, or maybe a
* finalizer.
*/
OBJ_CHECK_SLOT(this, slot);
return (OBJ_SCOPE(this)->title.ownercx == cx)
? LOCKED_OBJ_GET_SLOT(this, slot)
return (scope()->title.ownercx == cx)
? this->lockedGetSlot(slot)
: js_GetSlotThreadSafe(cx, this, slot);
#else
return LOCKED_OBJ_GET_SLOT(this, slot);
return this->lockedGetSlot(slot);
#endif
}
@ -72,12 +72,12 @@ JSObject::setSlotMT(JSContext *cx, uintN slot, jsval value)
#ifdef JS_THREADSAFE
/* Thread-safe way to set a slot. */
OBJ_CHECK_SLOT(this, slot);
if (OBJ_SCOPE(this)->title.ownercx == cx)
LOCKED_OBJ_SET_SLOT(this, slot, value);
if (scope()->title.ownercx == cx)
this->lockedSetSlot(slot, value);
else
js_SetSlotThreadSafe(cx, this, slot, value);
#else
LOCKED_OBJ_SET_SLOT(this, slot, value);
this->lockedSetSlot(slot, value);
#endif
}
@ -148,7 +148,7 @@ JSObject::initSharingEmptyScope(JSClass *clasp, JSObject *proto, JSObject *paren
{
init(clasp, proto, parent, privateSlotValue);
JSEmptyScope *emptyScope = OBJ_SCOPE(proto)->emptyScope;
JSEmptyScope *emptyScope = proto->scope()->emptyScope;
JS_ASSERT(emptyScope->clasp == clasp);
emptyScope->hold();
map = emptyScope;
@ -167,7 +167,7 @@ JSObject::unbrand(JSContext *cx)
{
if (this->isNative()) {
JS_LOCK_OBJ(cx, this);
JSScope *scope = OBJ_SCOPE(this);
JSScope *scope = this->scope();
if (scope->isSharedEmpty()) {
scope = js_GetMutableScope(cx, this);
if (!scope) {

View File

@ -279,7 +279,7 @@ ToDisassemblySource(JSContext *cx, jsval v)
if (clasp == &js_BlockClass) {
char *source = JS_sprintf_append(NULL, "depth %d {", OBJ_BLOCK_DEPTH(cx, obj));
for (JSScopeProperty *sprop = OBJ_SCOPE(obj)->lastProperty();
for (JSScopeProperty *sprop = obj->scope()->lastProperty();
sprop;
sprop = sprop->parent) {
const char *bytes = js_AtomToPrintableString(cx, JSID_TO_ATOM(sprop->id));
@ -1324,7 +1324,7 @@ GetLocal(SprintStack *ss, jsint i)
}
i -= depth;
for (sprop = OBJ_SCOPE(obj)->lastProperty(); sprop; sprop = sprop->parent) {
for (sprop = obj->scope()->lastProperty(); sprop; sprop = sprop->parent) {
if (sprop->shortid == i)
break;
}
@ -2645,7 +2645,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
MUST_FLOW_THROUGH("enterblock_out");
#define LOCAL_ASSERT_OUT(expr) LOCAL_ASSERT_CUSTOM(expr, ok = JS_FALSE; \
goto enterblock_out)
for (sprop = OBJ_SCOPE(obj)->lastProperty(); sprop;
for (sprop = obj->scope()->lastProperty(); sprop;
sprop = sprop->parent) {
if (!sprop->hasShortID())
continue;

View File

@ -608,7 +608,7 @@ END_CASE(JSOP_PICK)
JS_ASSERT((sprop)->slot != SPROP_INVALID_SLOT || \
!sprop->hasDefaultSetter()); \
*vp = ((sprop)->slot != SPROP_INVALID_SLOT) \
? LOCKED_OBJ_GET_SLOT(pobj, (sprop)->slot) \
? (pobj)->lockedGetSlot((sprop)->slot) \
: JSVAL_VOID; \
} else { \
if (!js_NativeGet(cx, obj, pobj, sprop, getHow, vp)) \
@ -621,9 +621,9 @@ END_CASE(JSOP_PICK)
TRACE_2(SetPropHit, entry, sprop); \
if (sprop->hasDefaultSetter() && \
(sprop)->slot != SPROP_INVALID_SLOT && \
!OBJ_SCOPE(obj)->brandedOrHasMethodBarrier()) { \
!(obj)->scope()->brandedOrHasMethodBarrier()) { \
/* Fast path for, e.g., plain Object instance properties. */ \
LOCKED_OBJ_SET_SLOT(obj, (sprop)->slot, *vp); \
(obj)->lockedSetSlot((sprop)->slot, *vp); \
} else { \
if (!js_NativeSet(cx, obj, sprop, false, vp)) \
goto error; \
@ -1208,14 +1208,14 @@ BEGIN_CASE(JSOP_NAMEDEC)
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
if (obj == obj2 && entry->vword.isSlot()) {
slot = entry->vword.toSlot();
JS_ASSERT(slot < OBJ_SCOPE(obj)->freeslot);
rval = LOCKED_OBJ_GET_SLOT(obj, slot);
JS_ASSERT(slot < obj->scope()->freeslot);
rval = obj->lockedGetSlot(slot);
if (JS_LIKELY(CAN_DO_FAST_INC_DEC(rval))) {
rtmp = rval;
rval += (js_CodeSpec[op].format & JOF_INC) ? 2 : -2;
if (!(js_CodeSpec[op].format & JOF_POST))
rtmp = rval;
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
obj->lockedSetSlot(slot, rval);
PUSH_OPND(rtmp);
len = JSOP_INCNAME_LENGTH;
DO_NEXT_OP(len);
@ -1472,8 +1472,8 @@ BEGIN_CASE(JSOP_GETXPROP)
rval = entry->vword.toJsval();
} else if (entry->vword.isSlot()) {
slot = entry->vword.toSlot();
JS_ASSERT(slot < OBJ_SCOPE(obj2)->freeslot);
rval = LOCKED_OBJ_GET_SLOT(obj2, slot);
JS_ASSERT(slot < obj2->scope()->freeslot);
rval = obj2->lockedGetSlot(slot);
} else {
JS_ASSERT(entry->vword.isSprop());
sprop = entry->vword.toSprop();
@ -1564,8 +1564,8 @@ BEGIN_CASE(JSOP_CALLPROP)
rval = entry->vword.toJsval();
} else if (entry->vword.isSlot()) {
slot = entry->vword.toSlot();
JS_ASSERT(slot < OBJ_SCOPE(obj2)->freeslot);
rval = LOCKED_OBJ_GET_SLOT(obj2, slot);
JS_ASSERT(slot < obj2->scope()->freeslot);
rval = obj2->lockedGetSlot(slot);
} else {
JS_ASSERT(entry->vword.isSprop());
sprop = entry->vword.toSprop();
@ -1682,7 +1682,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
JS_ASSERT(sprop->writable());
JS_ASSERT_IF(sprop->hasSlot(), entry->vcapTag() == 0);
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
JS_ASSERT(!scope->sealed());
/*
@ -1696,7 +1696,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
if (entry->vcapTag() == 0 ||
((obj2 = obj->getProto()) &&
obj2->isNative() &&
OBJ_SHAPE(obj2) == entry->vshape())) {
obj2->shape() == entry->vshape())) {
goto fast_set_propcache_hit;
}
@ -1790,7 +1790,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
* branded scope.
*/
TRACE_2(SetPropHit, entry, sprop);
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
obj->lockedSetSlot(slot, rval);
/*
* Purge the property cache of the id we may have just
@ -1812,7 +1812,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
if (obj == obj2) {
sprop = entry->vword.toSprop();
JS_ASSERT(sprop->writable());
JS_ASSERT(!OBJ_SCOPE(obj2)->sealed());
JS_ASSERT(!obj2->scope()->sealed());
NATIVE_SET(cx, obj, sprop, entry, &rval);
}
if (sprop)
@ -2284,8 +2284,8 @@ BEGIN_CASE(JSOP_CALLNAME)
if (entry->vword.isSlot()) {
slot = entry->vword.toSlot();
JS_ASSERT(slot < OBJ_SCOPE(obj2)->freeslot);
rval = LOCKED_OBJ_GET_SLOT(obj2, slot);
JS_ASSERT(slot < obj2->scope()->freeslot);
rval = obj2->lockedGetSlot(slot);
goto do_push_rval;
}
@ -2708,8 +2708,8 @@ BEGIN_CASE(JSOP_CALLDSLOT)
index = GET_UINT16(regs.pc);
JS_ASSERT(JS_INITIAL_NSLOTS + index < jsatomid(obj->dslots[-1]));
JS_ASSERT_IF(OBJ_SCOPE(obj)->object == obj,
JS_INITIAL_NSLOTS + index < OBJ_SCOPE(obj)->freeslot);
JS_ASSERT_IF(obj->scope()->object == obj,
JS_INITIAL_NSLOTS + index < obj->scope()->freeslot);
PUSH_OPND(obj->dslots[index]);
if (op == JSOP_CALLDSLOT)
@ -2760,12 +2760,12 @@ BEGIN_CASE(JSOP_SETGVAR)
} else {
slot = JSVAL_TO_INT(lval);
JS_LOCK_OBJ(cx, obj);
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
if (!scope->methodWriteBarrier(cx, slot, rval)) {
JS_UNLOCK_SCOPE(cx, scope);
goto error;
}
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
obj->lockedSetSlot(slot, rval);
JS_UNLOCK_SCOPE(cx, scope);
}
END_SET_CASE(JSOP_SETGVAR)
@ -2825,7 +2825,7 @@ BEGIN_CASE(JSOP_DEFVAR)
obj->isNative()) {
sprop = (JSScopeProperty *) prop;
if (!sprop->configurable() &&
SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)) &&
SPROP_HAS_VALID_SLOT(sprop, obj->scope()) &&
sprop->hasDefaultGetterOrIsMethod() &&
sprop->hasDefaultSetter()) {
/*
@ -3137,7 +3137,7 @@ BEGIN_CASE(JSOP_LAMBDA)
JS_ASSERT(!JSVAL_IS_PRIMITIVE(lval));
obj2 = JSVAL_TO_OBJECT(lval);
JS_ASSERT(obj2->getClass() == &js_ObjectClass);
JS_ASSERT(OBJ_SCOPE(obj2)->object == obj2);
JS_ASSERT(obj2->scope()->object == obj2);
break;
}
}
@ -3350,7 +3350,7 @@ BEGIN_CASE(JSOP_INITMETHOD)
JS_ASSERT(!obj->getClass()->reserveSlots);
JS_ASSERT(!(obj->getClass()->flags & JSCLASS_SHARE_ALL_PROPERTIES));
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
PropertyCacheEntry *entry;
/*
@ -3403,7 +3403,7 @@ BEGIN_CASE(JSOP_INITMETHOD)
* contain a method of a branded scope.
*/
TRACE_2(SetPropHit, entry, sprop);
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
obj->lockedSetSlot(slot, rval);
} else {
PCMETER(JS_PROPERTY_CACHE(cx).inipcmisses++);

View File

@ -3211,7 +3211,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
/*
* Define the let binding's property before storing pn in a reserved slot,
* since block_reserveSlots depends on OBJ_SCOPE(blockObj)->entryCount.
* since block_reserveSlots depends on blockObj->scope()->entryCount.
*/
if (!js_DefineBlockVariable(cx, blockObj, ATOM_TO_JSID(atom), n))
return JS_FALSE;
@ -3227,7 +3227,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
!js_GrowSlots(cx, blockObj, slot + 1)) {
return JS_FALSE;
}
OBJ_SCOPE(blockObj)->freeslot = slot + 1;
blockObj->scope()->freeslot = slot + 1;
blockObj->setSlot(slot, PRIVATE_TO_JSVAL(pn));
return JS_TRUE;
}
@ -3239,7 +3239,7 @@ PopStatement(JSTreeContext *tc)
if (stmt->flags & SIF_SCOPE) {
JSObject *obj = stmt->blockObj;
JSScope *scope = OBJ_SCOPE(obj);
JSScope *scope = obj->scope();
JS_ASSERT(!OBJ_IS_CLONED_BLOCK(obj));
for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {

View File

@ -71,7 +71,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
* Check for fill from js_SetPropertyHelper where the setter removed sprop
* from pobj's scope (via unwatch or delete, e.g.).
*/
scope = OBJ_SCOPE(pobj);
scope = pobj->scope();
if (!scope->hasProperty(sprop)) {
PCMETER(oddfills++);
return JS_NO_PROP_CACHE_FILL;
@ -149,7 +149,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
JS_ASSERT(scope->hasMethodBarrier());
v = sprop->methodValue();
JS_ASSERT(VALUE_IS_FUNCTION(cx, v));
JS_ASSERT(v == LOCKED_OBJ_GET_SLOT(pobj, sprop->slot));
JS_ASSERT(v == pobj->lockedGetSlot(sprop->slot));
vword.setObject(JSVAL_TO_OBJECT(v));
break;
}
@ -157,7 +157,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
if (!scope->generic() &&
sprop->hasDefaultGetter() &&
SPROP_HAS_VALID_SLOT(sprop, scope)) {
v = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
v = pobj->lockedGetSlot(sprop->slot);
if (VALUE_IS_FUNCTION(cx, v)) {
/*
* Great, we have a function-valued prototype property
@ -179,7 +179,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
pobj, pobj->getClass()->name,
JSVAL_TO_OBJECT(v),
JS_GetFunctionName(GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v))),
OBJ_SHAPE(obj));
obj->shape());
#endif
if (!scope->brand(cx, sprop->slot, v))
return JS_NO_PROP_CACHE_FILL;
@ -246,7 +246,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
JSObject *proto = obj->getProto();
if (!proto || !proto->isNative())
return JS_NO_PROP_CACHE_FILL;
JSScope *protoscope = OBJ_SCOPE(proto);
JSScope *protoscope = proto->scope();
if (!protoscope->emptyScope ||
protoscope->emptyScope->clasp != obj->getClass()) {
return JS_NO_PROP_CACHE_FILL;
@ -264,7 +264,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
} while (0);
if (kshape == 0) {
kshape = OBJ_SHAPE(obj);
kshape = obj->shape();
vshape = scope->shape;
}
JS_ASSERT(kshape < SHAPE_OVERFLOW_BIT);
@ -354,7 +354,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
pc - cx->fp->script->code,
entry->kpc - cx->fp->script->code,
entry->kshape,
OBJ_SHAPE(obj));
obj->shape());
js_Disassemble1(cx, cx->fp->script, pc,
pc - cx->fp->script->code,
JS_FALSE, stderr);
@ -401,8 +401,8 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
jsid id = ATOM_TO_JSID(atom);
id = js_CheckForStringIndex(id);
JS_ASSERT(OBJ_SCOPE(pobj)->lookup(id));
JS_ASSERT_IF(OBJ_SCOPE(pobj)->object, OBJ_SCOPE(pobj)->object == pobj);
JS_ASSERT(pobj->scope()->lookup(id));
JS_ASSERT_IF(pobj->scope()->object, pobj->scope()->object == pobj);
#endif
*pobjp = pobj;
return NULL;

View File

@ -252,7 +252,7 @@ class PropertyCache
/*
* Fill property cache entry for key cx->fp->pc, optimized value word
* computed from obj and sprop, and entry capability forged from 24-bit
* OBJ_SHAPE(obj), 4-bit scopeIndex, and 4-bit protoIndex.
* obj->shape(), 4-bit scopeIndex, and 4-bit protoIndex.
*
* Return the filled cache entry or JS_NO_PROP_CACHE_FILL if caching was
* not possible.

View File

@ -50,7 +50,7 @@ using namespace js;
/* static */ inline bool
PropertyCache::matchShape(JSContext *cx, JSObject *obj, uint32 shape)
{
return CX_OWNS_OBJECT_TITLE(cx, obj) && OBJ_SHAPE(obj) == shape;
return CX_OWNS_OBJECT_TITLE(cx, obj) && obj->shape() == shape;
}
/*

View File

@ -97,7 +97,7 @@ js_GetMutableScope(JSContext *cx, JSObject *obj)
JSClass *clasp;
uint32 freeslot;
scope = OBJ_SCOPE(obj);
scope = obj->scope();
JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
if (!scope->isSharedEmpty())
return scope;
@ -120,8 +120,8 @@ js_GetMutableScope(JSContext *cx, JSObject *obj)
clasp = obj->getClass();
if (clasp->reserveSlots) {
/*
* FIXME: Here we change OBJ_SCOPE(obj)->freeslot without changing
* OBJ_SHAPE(obj). If we strengthen the shape guarantees to cover
* FIXME: Here we change obj->scope()->freeslot without changing
* obj->shape(). If we strengthen the shape guarantees to cover
* freeslot, we can eliminate a check in JSOP_SETPROP and in
* js_AddProperty. See bug 535416.
*/
@ -1143,7 +1143,7 @@ JSScope::clear(JSContext *cx)
uint32 newShape;
if (proto &&
proto->isNative() &&
(emptyScope = OBJ_SCOPE(proto)->emptyScope) &&
(emptyScope = proto->scope()->emptyScope) &&
emptyScope->clasp == clasp) {
newShape = emptyScope->shape;
} else {
@ -1167,7 +1167,7 @@ JSScope::methodShapeChange(JSContext *cx, JSScopeProperty *sprop, jsval toval)
JS_ASSERT(!JSVAL_IS_NULL(sprop->id));
if (sprop->isMethod()) {
#ifdef DEBUG
jsval prev = LOCKED_OBJ_GET_SLOT(object, sprop->slot);
jsval prev = object->lockedGetSlot(sprop->slot);
JS_ASSERT(sprop->methodValue() == prev);
JS_ASSERT(hasMethodBarrier());
JS_ASSERT(object->getClass() == &js_ObjectClass);

View File

@ -541,17 +541,31 @@ JS_IS_SCOPE_LOCKED(JSContext *cx, JSScope *scope)
}
inline JSScope *
OBJ_SCOPE(JSObject *obj)
JSObject::scope() const
{
JS_ASSERT(obj->isNative());
return (JSScope *) obj->map;
JS_ASSERT(isNative());
return (JSScope *) map;
}
inline uint32
OBJ_SHAPE(JSObject *obj)
JSObject::shape() const
{
JS_ASSERT(obj->map->shape != JSObjectMap::SHAPELESS);
return obj->map->shape;
JS_ASSERT(map->shape != JSObjectMap::SHAPELESS);
return map->shape;
}
inline jsval
JSObject::lockedGetSlot(uintN slot) const
{
OBJ_CHECK_SLOT(this, slot);
return this->getSlot(slot);
}
inline void
JSObject::lockedSetSlot(uintN slot, jsval value)
{
OBJ_CHECK_SLOT(this, slot);
this->setSlot(slot, value);
}
/*
@ -973,7 +987,7 @@ JSScopeProperty::get(JSContext* cx, JSObject* obj, JSObject *pobj, jsval* vp)
if (isMethod()) {
*vp = methodValue();
JSScope *scope = OBJ_SCOPE(pobj);
JSScope *scope = pobj->scope();
JS_ASSERT(scope->object == pobj);
return scope->methodReadBarrier(cx, this, vp);
}

View File

@ -137,7 +137,7 @@ inline bool
JSScope::methodWriteBarrier(JSContext *cx, JSScopeProperty *sprop, jsval v)
{
if (flags & (BRANDED | METHOD_BARRIER)) {
jsval prev = LOCKED_OBJ_GET_SLOT(object, sprop->slot);
jsval prev = object->lockedGetSlot(sprop->slot);
if (prev != v && VALUE_IS_FUNCTION(cx, prev))
return methodShapeChange(cx, sprop, v);
@ -149,7 +149,7 @@ inline bool
JSScope::methodWriteBarrier(JSContext *cx, uint32 slot, jsval v)
{
if (flags & (BRANDED | METHOD_BARRIER)) {
jsval prev = LOCKED_OBJ_GET_SLOT(object, slot);
jsval prev = object->lockedGetSlot(slot);
if (prev != v && VALUE_IS_FUNCTION(cx, prev))
return methodShapeChange(cx, slot, v);

View File

@ -1120,7 +1120,7 @@ GlobalSlotHash(JSContext* cx, unsigned slot)
fp = fp->down;
HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
HashAccum(h, uintptr_t(OBJ_SHAPE(fp->scopeChain->getGlobal())), ORACLE_MASK);
HashAccum(h, uintptr_t(fp->scopeChain->getGlobal()->shape()), ORACLE_MASK);
HashAccum(h, uintptr_t(slot), ORACLE_MASK);
return int(h);
}
@ -1539,7 +1539,7 @@ AttemptCompilation(JSContext *cx, JSObject* globalObj, jsbytecode* pc, uint32 ar
ResetRecordingAttempts(cx, pc);
/* Breathe new life into all peer fragments at the designated loop header. */
TreeFragment* f = LookupLoop(tm, pc, globalObj, OBJ_SHAPE(globalObj), argc);
TreeFragment* f = LookupLoop(tm, pc, globalObj, globalObj->shape(), argc);
if (!f) {
/*
* If the global object's shape changed, we can't easily find the
@ -2212,7 +2212,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
fragment->profFragID);
debug_only_printf(LC_TMTracer, "globalObj=%p, shape=%d\n",
(void*)this->globalObj, OBJ_SHAPE(this->globalObj));
(void*)this->globalObj, this->globalObj->shape());
debug_only_printf(LC_TMTreeVis, "TREEVIS RECORD FRAG=%p ANCHOR=%p\n", (void*)fragment,
(void*)anchor);
#endif
@ -5255,11 +5255,11 @@ TraceRecorder::hasMethod(JSObject* obj, jsid id, bool& found)
// it's there now, if found in a non-native object.
status = RECORD_STOP;
} else {
JSScope* scope = OBJ_SCOPE(pobj);
JSScope* scope = pobj->scope();
JSScopeProperty* sprop = (JSScopeProperty*) prop;
if (sprop->hasDefaultGetterOrIsMethod() && SPROP_HAS_VALID_SLOT(sprop, scope)) {
jsval v = LOCKED_OBJ_GET_SLOT(pobj, sprop->slot);
jsval v = pobj->lockedGetSlot(sprop->slot);
if (VALUE_IS_FUNCTION(cx, v)) {
found = true;
if (!scope->generic() && !scope->branded() && !scope->brand(cx, sprop->slot, v))
@ -5300,7 +5300,7 @@ CheckGlobalObjectShape(JSContext* cx, TraceMonitor* tm, JSObject* globalObj,
return false;
}
uint32 globalShape = OBJ_SHAPE(globalObj);
uint32 globalShape = globalObj->shape();
if (tm->recorder) {
TreeFragment* root = tm->recorder->getFragment()->root;
@ -5915,7 +5915,7 @@ JS_REQUIRES_STACK bool
TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount)
{
#ifdef JS_THREADSAFE
if (OBJ_SCOPE(cx->fp->scopeChain->getGlobal())->title.ownercx != cx) {
if (cx->fp->scopeChain->getGlobal()->scope()->title.ownercx != cx) {
AbortRecording(cx, "Global object not owned by this context");
return false; /* we stay away from shared global objects */
}
@ -6445,7 +6445,7 @@ ScopeChainCheck(JSContext* cx, TreeFragment* f)
JS_ASSERT(f->globalObj->numSlots() <= MAX_GLOBAL_SLOTS);
JS_ASSERT(f->nGlobalTypes() == f->globalSlots->length());
JS_ASSERT_IF(f->globalSlots->length() != 0,
OBJ_SHAPE(f->globalObj) == f->globalShape);
f->globalObj->shape() == f->globalShape);
return true;
}
@ -7864,7 +7864,7 @@ TraceRecorder::scopeChainProp(JSObject* chainHead, jsval*& vp, LIns*& ins, NameR
obj2->dropProperty(cx, prop);
RETURN_STOP_A("prototype property");
}
if (!isValidSlot(OBJ_SCOPE(obj), sprop)) {
if (!isValidSlot(obj->scope(), sprop)) {
obj2->dropProperty(cx, prop);
return ARECORD_STOP;
}
@ -9012,7 +9012,7 @@ static FILE* shapefp = NULL;
static void
DumpShape(JSObject* obj, const char* prefix)
{
JSScope* scope = OBJ_SCOPE(obj);
JSScope* scope = obj->scope();
if (!shapefp) {
shapefp = fopen("/tmp/shapes.dump", "w");
@ -9265,7 +9265,7 @@ TraceRecorder::guardPropertyCacheHit(LIns* obj_ins,
// For any hit that goes up the scope and/or proto chains, we will need to
// guard on the shape of the object containing the property.
if (entry->vcapTag() >= 1) {
JS_ASSERT(OBJ_SHAPE(obj2) == vshape);
JS_ASSERT(obj2->shape() == vshape);
if (obj2 == globalObj)
RETURN_STOP("hitting the global object via a prototype chain");
@ -9567,7 +9567,7 @@ TraceRecorder::guardPrototypeHasNoIndexedProperties(JSObject* obj, LIns* obj_ins
return RECORD_STOP;
while (guardHasPrototype(obj, obj_ins, &obj, &obj_ins, exit))
CHECK_STATUS(guardShape(obj_ins, obj, OBJ_SHAPE(obj), "guard(shape)", exit));
CHECK_STATUS(guardShape(obj_ins, obj, obj->shape(), "guard(shape)", exit));
return RECORD_CONTINUE;
}
@ -10359,7 +10359,7 @@ TraceRecorder::getClassPrototype(JSObject* ctor, LIns*& proto_ins)
// that pval is usable.
JS_ASSERT(!JSVAL_IS_PRIMITIVE(pval));
JSObject *proto = JSVAL_TO_OBJECT(pval);
JS_ASSERT_IF(clasp != &js_ArrayClass, OBJ_SCOPE(proto)->emptyScope->clasp == clasp);
JS_ASSERT_IF(clasp != &js_ArrayClass, proto->scope()->emptyScope->clasp == clasp);
proto_ins = INS_CONSTOBJ(proto);
return RECORD_CONTINUE;
@ -10383,7 +10383,7 @@ TraceRecorder::getClassPrototype(JSProtoKey key, LIns*& proto_ins)
/* Double-check that a native proto has a matching emptyScope. */
if (key != JSProto_Array) {
JS_ASSERT(proto->isNative());
JSEmptyScope *emptyScope = OBJ_SCOPE(proto)->emptyScope;
JSEmptyScope *emptyScope = proto->scope()->emptyScope;
JS_ASSERT(emptyScope);
JS_ASSERT(JSCLASS_CACHED_PROTO_KEY(emptyScope->clasp) == key);
}
@ -11165,7 +11165,7 @@ JS_REQUIRES_STACK RecordingStatus
TraceRecorder::nativeSet(JSObject* obj, LIns* obj_ins, JSScopeProperty* sprop,
jsval v, LIns* v_ins)
{
JSScope* scope = OBJ_SCOPE(obj);
JSScope* scope = obj->scope();
uint32 slot = sprop->slot;
/*
@ -11219,7 +11219,7 @@ MethodWriteBarrier(JSContext* cx, JSObject* obj, JSScopeProperty* sprop, JSObjec
{
AutoValueRooter tvr(cx, funobj);
return OBJ_SCOPE(obj)->methodWriteBarrier(cx, sprop, tvr.value());
return obj->scope()->methodWriteBarrier(cx, sprop, tvr.value());
}
JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, MethodWriteBarrier, CONTEXT, OBJECT, SCOPEPROP, OBJECT,
0, ACC_STORE_ANY)
@ -11246,7 +11246,7 @@ TraceRecorder::setProp(jsval &l, PropertyCacheEntry* entry, JSScopeProperty* spr
JSObject* obj = JSVAL_TO_OBJECT(l);
LIns* obj_ins = get(&l);
JS_ASSERT_IF(entry->directHit(), OBJ_SCOPE(obj)->hasProperty(sprop));
JS_ASSERT_IF(entry->directHit(), obj->scope()->hasProperty(sprop));
// Fast path for CallClass. This is about 20% faster than the general case.
v_ins = get(&v);
@ -11259,7 +11259,7 @@ TraceRecorder::setProp(jsval &l, PropertyCacheEntry* entry, JSScopeProperty* spr
obj2 = obj2->getParent();
for (jsuword j = entry->protoIndex(); j; j--)
obj2 = obj2->getProto();
JSScope *scope = OBJ_SCOPE(obj2);
JSScope *scope = obj2->scope();
JS_ASSERT_IF(entry->adding(), obj2 == obj);
// Guard before anything else.
@ -12747,7 +12747,7 @@ TraceRecorder::name(jsval*& vp, LIns*& ins, NameResult& nr)
/* Don't trace getter or setter calls, our caller wants a direct slot. */
if (pcval.isSprop()) {
JSScopeProperty* sprop = pcval.toSprop();
if (!isValidSlot(OBJ_SCOPE(obj), sprop))
if (!isValidSlot(obj->scope(), sprop))
RETURN_STOP_A("name() not accessing a valid slot");
slot = sprop->slot;
} else {
@ -12770,7 +12770,7 @@ MethodReadBarrier(JSContext* cx, JSObject* obj, JSScopeProperty* sprop, JSObject
{
AutoValueRooter tvr(cx, funobj);
if (!OBJ_SCOPE(obj)->methodReadBarrier(cx, sprop, tvr.addr()))
if (!obj->scope()->methodReadBarrier(cx, sprop, tvr.addr()))
return NULL;
JS_ASSERT(VALUE_IS_FUNCTION(cx, tvr.value()));
return JSVAL_TO_OBJECT(tvr.value());
@ -12840,7 +12840,7 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp,
VMSideExit* exit = snapshot(BRANCH_EXIT);
do {
if (obj->isNative()) {
CHECK_STATUS_A(InjectStatus(guardShape(obj_ins, obj, OBJ_SHAPE(obj),
CHECK_STATUS_A(InjectStatus(guardShape(obj_ins, obj, obj->shape(),
"guard(shape)", exit)));
} else if (!guardDenseArray(obj, obj_ins, exit)) {
RETURN_STOP_A("non-native object involved in undefined property access");
@ -12868,7 +12868,7 @@ TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, PCVal pcva
if (pcval.isSprop()) {
sprop = pcval.toSprop();
JS_ASSERT(OBJ_SCOPE(obj2)->hasProperty(sprop));
JS_ASSERT(obj2->scope()->hasProperty(sprop));
if (setflags && !sprop->hasDefaultSetter())
RETURN_STOP_A("non-stub setter");
@ -12883,11 +12883,11 @@ TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, PCVal pcva
return InjectStatus(getPropertyWithNativeGetter(obj_ins, sprop, outp));
return InjectStatus(getPropertyById(obj_ins, outp));
}
if (!SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)))
if (!SPROP_HAS_VALID_SLOT(sprop, obj2->scope()))
RETURN_STOP_A("no valid slot");
slot = sprop->slot;
isMethod = sprop->isMethod();
JS_ASSERT_IF(isMethod, OBJ_SCOPE(obj2)->hasMethodBarrier());
JS_ASSERT_IF(isMethod, obj2->scope()->hasMethodBarrier());
} else {
if (!pcval.isSlot())
RETURN_STOP_A("PCE is not a slot");
@ -13634,7 +13634,7 @@ TraceRecorder::traverseScopeChain(JSObject *obj, LIns *obj_ins, JSObject *target
if (!exit)
exit = snapshot(BRANCH_EXIT);
guard(true,
addName(lir->ins2i(LIR_eq, shape_ins, OBJ_SHAPE(obj)), "guard_shape"),
addName(lir->ins2i(LIR_eq, shape_ins, obj->shape()), "guard_shape"),
exit);
}
}

View File

@ -4912,7 +4912,7 @@ xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
* property's getter or setter. But now it's time to remove any such
* property, to purge the property cache and remove the scope entry.
*/
if (OBJ_SCOPE(obj)->object == obj && !js_DeleteProperty(cx, obj, id, rval))
if (obj->scope()->object == obj && !js_DeleteProperty(cx, obj, id, rval))
return JS_FALSE;
*rval = JSVAL_TRUE;
@ -7283,7 +7283,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
}
JS_ASSERT(prop);
sprop = (JSScopeProperty *) prop;
JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, pobj->scope()));
cval = pobj->getSlotMT(cx, sprop->slot);
pobj->dropProperty(cx, prop);
JS_ASSERT(VALUE_IS_FUNCTION(cx, cval));

View File

@ -3106,7 +3106,7 @@ ShapeOf(JSContext *cx, uintN argc, jsval *vp)
*vp = INT_TO_JSVAL(-1);
return JS_TRUE;
}
return JS_NewNumberValue(cx, OBJ_SHAPE(obj), vp);
return JS_NewNumberValue(cx, obj->shape(), vp);
}
#ifdef JS_THREADSAFE