mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 500431 part 4 - Encapsulate PropertyCacheEntry::pcval. r=brendan.
This commit is contained in:
parent
d26dffb193
commit
785e3b6713
@ -2252,23 +2252,23 @@ AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, JSFrameRegs& regs,
|
||||
JS_ASSERT(pobj == found);
|
||||
|
||||
JSScopeProperty *sprop = (JSScopeProperty *) prop;
|
||||
if (PCVAL_IS_SLOT(entry->vword)) {
|
||||
JS_ASSERT(PCVAL_TO_SLOT(entry->vword) == sprop->slot);
|
||||
if (entry->vword.isSlot()) {
|
||||
JS_ASSERT(entry->vword.toSlot() == sprop->slot);
|
||||
JS_ASSERT(!sprop->isMethod());
|
||||
} else if (PCVAL_IS_SPROP(entry->vword)) {
|
||||
JS_ASSERT(PCVAL_TO_SPROP(entry->vword) == sprop);
|
||||
} 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));
|
||||
} else {
|
||||
jsval v;
|
||||
JS_ASSERT(PCVAL_IS_OBJECT(entry->vword));
|
||||
JS_ASSERT(entry->vword != PCVAL_NULL);
|
||||
JS_ASSERT(entry->vword.isObject());
|
||||
JS_ASSERT(!entry->vword.isNull());
|
||||
JS_ASSERT(OBJ_SCOPE(pobj)->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(VALUE_IS_FUNCTION(cx, v));
|
||||
JS_ASSERT(PCVAL_TO_OBJECT(entry->vword) == JSVAL_TO_OBJECT(v));
|
||||
JS_ASSERT(entry->vword.toObject() == JSVAL_TO_OBJECT(v));
|
||||
|
||||
if (sprop->isMethod()) {
|
||||
JS_ASSERT(js_CodeSpec[*regs.pc].format & JOF_CALLOP);
|
||||
|
@ -1223,8 +1223,8 @@ BEGIN_CASE(JSOP_NAMEDEC)
|
||||
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
|
||||
if (obj == obj2 && PCVAL_IS_SLOT(entry->vword)) {
|
||||
slot = PCVAL_TO_SLOT(entry->vword);
|
||||
if (obj == obj2 && entry->vword.isSlot()) {
|
||||
slot = entry->vword.toSlot();
|
||||
JS_ASSERT(slot < OBJ_SCOPE(obj)->freeslot);
|
||||
rval = LOCKED_OBJ_GET_SLOT(obj, slot);
|
||||
if (JS_LIKELY(CAN_DO_FAST_INC_DEC(rval))) {
|
||||
@ -1487,15 +1487,15 @@ BEGIN_CASE(JSOP_GETXPROP)
|
||||
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(i, aobj, obj2, entry);
|
||||
if (PCVAL_IS_OBJECT(entry->vword)) {
|
||||
rval = PCVAL_OBJECT_TO_JSVAL(entry->vword);
|
||||
} else if (PCVAL_IS_SLOT(entry->vword)) {
|
||||
slot = PCVAL_TO_SLOT(entry->vword);
|
||||
if (entry->vword.isObject()) {
|
||||
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);
|
||||
} else {
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
NATIVE_GET(cx, obj, obj2, sprop,
|
||||
fp->imacpc ? JSGET_NO_METHOD_BARRIER : JSGET_METHOD_BARRIER,
|
||||
&rval);
|
||||
@ -1583,15 +1583,15 @@ BEGIN_CASE(JSOP_CALLPROP)
|
||||
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, aobj, obj2, entry);
|
||||
if (PCVAL_IS_OBJECT(entry->vword)) {
|
||||
rval = PCVAL_OBJECT_TO_JSVAL(entry->vword);
|
||||
} else if (PCVAL_IS_SLOT(entry->vword)) {
|
||||
slot = PCVAL_TO_SLOT(entry->vword);
|
||||
if (entry->vword.isObject()) {
|
||||
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);
|
||||
} else {
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
NATIVE_GET(cx, obj, obj2, sprop, JSGET_NO_METHOD_BARRIER, &rval);
|
||||
}
|
||||
STORE_OPND(-1, rval);
|
||||
@ -1709,8 +1709,8 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
||||
* added directly to obj by this set, or on an existing "own"
|
||||
* property, or on a prototype property that has a setter.
|
||||
*/
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
JS_ASSERT(sprop->writable());
|
||||
JS_ASSERT_IF(sprop->hasSlot(), entry->vcapTag() == 0);
|
||||
|
||||
@ -1843,8 +1843,8 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
|
||||
sprop = NULL;
|
||||
if (obj == obj2) {
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
JS_ASSERT(sprop->writable());
|
||||
JS_ASSERT(!OBJ_SCOPE(obj2)->sealed());
|
||||
NATIVE_SET(cx, obj, sprop, entry, &rval);
|
||||
@ -2295,20 +2295,20 @@ BEGIN_CASE(JSOP_CALLNAME)
|
||||
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
|
||||
if (PCVAL_IS_OBJECT(entry->vword)) {
|
||||
rval = PCVAL_OBJECT_TO_JSVAL(entry->vword);
|
||||
if (entry->vword.isObject()) {
|
||||
rval = entry->vword.toJsval();
|
||||
goto do_push_rval;
|
||||
}
|
||||
|
||||
if (PCVAL_IS_SLOT(entry->vword)) {
|
||||
slot = PCVAL_TO_SLOT(entry->vword);
|
||||
if (entry->vword.isSlot()) {
|
||||
slot = entry->vword.toSlot();
|
||||
JS_ASSERT(slot < OBJ_SCOPE(obj2)->freeslot);
|
||||
rval = LOCKED_OBJ_GET_SLOT(obj2, slot);
|
||||
goto do_push_rval;
|
||||
}
|
||||
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
goto do_native_get;
|
||||
}
|
||||
} else {
|
||||
@ -3400,8 +3400,8 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
||||
PCMETER(cache->pchits++);
|
||||
PCMETER(cache->inipchits++);
|
||||
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(entry->vword.isSprop());
|
||||
sprop = entry->vword.toSprop();
|
||||
JS_ASSERT(sprop->writable());
|
||||
|
||||
/*
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
using namespace js;
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(PCVal) == sizeof(jsuword));
|
||||
|
||||
JS_REQUIRES_STACK PropertyCacheEntry *
|
||||
PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoIndex,
|
||||
JSObject *pobj, JSScopeProperty *sprop, JSBool adding)
|
||||
@ -53,7 +55,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
||||
jsuword kshape, vshape;
|
||||
JSOp op;
|
||||
const JSCodeSpec *cs;
|
||||
jsuword vword;
|
||||
PCVal vword;
|
||||
PropertyCacheEntry *entry;
|
||||
|
||||
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
|
||||
@ -148,7 +150,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
||||
v = sprop->methodValue();
|
||||
JS_ASSERT(VALUE_IS_FUNCTION(cx, v));
|
||||
JS_ASSERT(v == LOCKED_OBJ_GET_SLOT(pobj, sprop->slot));
|
||||
vword = JSVAL_OBJECT_TO_PCVAL(v);
|
||||
vword.setObject(JSVAL_TO_OBJECT(v));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -182,7 +184,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
||||
if (!scope->brand(cx, sprop->slot, v))
|
||||
return JS_NO_PROP_CACHE_FILL;
|
||||
}
|
||||
vword = JSVAL_OBJECT_TO_PCVAL(v);
|
||||
vword.setObject(JSVAL_TO_OBJECT(v));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -193,10 +195,10 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
||||
sprop->hasDefaultGetter() &&
|
||||
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);
|
||||
vword.setSlot(sprop->slot);
|
||||
} else {
|
||||
/* Best we can do is to cache sprop (still a nice speedup). */
|
||||
vword = SPROP_TO_PCVAL(sprop);
|
||||
vword.setSprop(sprop);
|
||||
if (adding &&
|
||||
sprop == scope->lastProperty() &&
|
||||
scope->shape == sprop->shape) {
|
||||
@ -290,7 +292,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
|
||||
JS_ASSERT(vshape < SHAPE_OVERFLOW_BIT);
|
||||
|
||||
entry = &table[hash(pc, kshape)];
|
||||
PCMETER(PCVAL_IS_NULL(entry->vword) || recycles++);
|
||||
PCMETER(entry->vword.isNull() || recycles++);
|
||||
entry->assign(pc, kshape, vshape, scopeIndex, protoIndex, vword);
|
||||
|
||||
empty = false;
|
||||
@ -416,13 +418,11 @@ PropertyCache::assertEmpty()
|
||||
JS_ASSERT(!table[i].kpc);
|
||||
JS_ASSERT(!table[i].kshape);
|
||||
JS_ASSERT(!table[i].vcap);
|
||||
JS_ASSERT(!table[i].vword);
|
||||
JS_ASSERT(table[i].vword.isNull());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_STATIC_ASSERT(PCVAL_NULL == 0);
|
||||
|
||||
void
|
||||
PropertyCache::purge(JSContext *cx)
|
||||
{
|
||||
@ -432,6 +432,7 @@ PropertyCache::purge(JSContext *cx)
|
||||
}
|
||||
|
||||
PodArrayZero(table);
|
||||
JS_ASSERT(table[0].vword.isNull());
|
||||
empty = true;
|
||||
|
||||
#ifdef JS_PROPERTY_CACHE_METERING
|
||||
@ -497,7 +498,8 @@ PropertyCache::purgeForScript(JSScript *script)
|
||||
if (JS_UPTRDIFF(entry->kpc, script->code) < script->length) {
|
||||
entry->kpc = NULL;
|
||||
#ifdef DEBUG
|
||||
entry->kshape = entry->vcap = entry->vword = 0;
|
||||
entry->kshape = entry->vcap = 0;
|
||||
entry->vword.setNull();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -69,12 +69,51 @@ enum {
|
||||
|
||||
const uint32 SHAPE_OVERFLOW_BIT = JS_BIT(32 - PCVCAP_TAGBITS);
|
||||
|
||||
/*
|
||||
* Property cache value. This is simply a tagged union:
|
||||
* PCVal = (JSObject * | uint32 | JSScopeProperty *).
|
||||
* It is the type of PropertyCacheEntry::vword and combines with the tag bits
|
||||
* of PropertyCacheEntry::vcap to tell how to get or set the property, once a
|
||||
* property cache hit is validated.
|
||||
*
|
||||
* PropertyCache::purge depends on the bit-pattern of a null PCVal being 0.
|
||||
*/
|
||||
class PCVal
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
OBJECT = 0,
|
||||
SLOT = 1,
|
||||
SPROP = 2,
|
||||
TAG = 3
|
||||
};
|
||||
|
||||
jsuword v;
|
||||
|
||||
public:
|
||||
bool isNull() const { return v == 0; }
|
||||
void setNull() { v = 0; }
|
||||
|
||||
bool isObject() const { return (v & TAG) == OBJECT; }
|
||||
JSObject *toObject() const { JS_ASSERT(isObject()); return reinterpret_cast<JSObject *>(v); }
|
||||
jsval toJsval() const { return OBJECT_TO_JSVAL(toObject()); }
|
||||
void setObject(JSObject *obj) { v = reinterpret_cast<jsuword>(obj); }
|
||||
|
||||
bool isSlot() const { return v & SLOT; }
|
||||
uint32 toSlot() const { JS_ASSERT(isSlot()); return uint32(v) >> 1; }
|
||||
void setSlot(uint32 slot) { v = (jsuword(slot) << 1) | SLOT; }
|
||||
|
||||
bool isSprop() const { return (v & TAG) == SPROP; }
|
||||
JSScopeProperty *toSprop() const { JS_ASSERT(isSprop()); return reinterpret_cast<JSScopeProperty *>(v & ~TAG); }
|
||||
void setSprop(JSScopeProperty *sprop) { JS_ASSERT(sprop); v = reinterpret_cast<jsuword>(sprop) | SPROP; }
|
||||
};
|
||||
|
||||
struct PropertyCacheEntry
|
||||
{
|
||||
jsbytecode *kpc; /* pc of cache-testing bytecode */
|
||||
jsuword kshape; /* shape of direct (key) object */
|
||||
jsuword vcap; /* value capability, see above */
|
||||
jsuword vword; /* value word, see PCVAL_* below */
|
||||
PCVal vword; /* value word, see PCVal above */
|
||||
|
||||
bool adding() const { return vcapTag() == 0 && kshape != vshape(); }
|
||||
bool directHit() const { return vcapTag() == 0 && kshape == vshape(); }
|
||||
@ -85,7 +124,7 @@ struct PropertyCacheEntry
|
||||
jsuword protoIndex() const { return vcap & PCVCAP_PROTOMASK; }
|
||||
|
||||
void assign(jsbytecode *kpc, jsuword kshape, jsuword vshape,
|
||||
uintN scopeIndex, uintN protoIndex, jsuword vword) {
|
||||
uintN scopeIndex, uintN protoIndex, PCVal vword) {
|
||||
JS_ASSERT(kshape < SHAPE_OVERFLOW_BIT);
|
||||
JS_ASSERT(vshape < SHAPE_OVERFLOW_BIT);
|
||||
JS_ASSERT(scopeIndex <= PCVCAP_SCOPEMASK);
|
||||
@ -195,41 +234,6 @@ struct PropertyCache
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Property cache value tagging/untagging macros.
|
||||
*/
|
||||
enum {
|
||||
PCVAL_OBJECT = 0,
|
||||
PCVAL_SLOT = 1,
|
||||
PCVAL_SPROP = 2,
|
||||
|
||||
PCVAL_TAGBITS = 2,
|
||||
PCVAL_TAGMASK = JS_BITMASK(PCVAL_TAGBITS),
|
||||
|
||||
PCVAL_NULL = 0
|
||||
};
|
||||
|
||||
inline jsuword PCVAL_TAG(jsuword v) { return v & PCVAL_TAGMASK; }
|
||||
inline jsuword PCVAL_CLRTAG(jsuword v) { return v & ~jsuword(PCVAL_TAGMASK); }
|
||||
inline jsuword PCVAL_SETTAG(jsuword v, jsuword t) { return v | t; }
|
||||
|
||||
inline bool PCVAL_IS_NULL(jsuword v) { return v == PCVAL_NULL; }
|
||||
|
||||
inline bool PCVAL_IS_OBJECT(jsuword v) { return PCVAL_TAG(v) == PCVAL_OBJECT; }
|
||||
inline JSObject *PCVAL_TO_OBJECT(jsuword v) { JS_ASSERT(PCVAL_IS_OBJECT(v)); return (JSObject *) v; }
|
||||
inline jsuword OBJECT_TO_PCVAL(JSObject *obj) { return jsuword(obj); }
|
||||
|
||||
inline jsval PCVAL_OBJECT_TO_JSVAL(jsuword v) { return OBJECT_TO_JSVAL(PCVAL_TO_OBJECT(v)); }
|
||||
inline jsuword JSVAL_OBJECT_TO_PCVAL(jsval v) { return OBJECT_TO_PCVAL(JSVAL_TO_OBJECT(v)); }
|
||||
|
||||
inline bool PCVAL_IS_SLOT(jsuword v) { return v & PCVAL_SLOT; }
|
||||
inline jsuint PCVAL_TO_SLOT(jsuword v) { JS_ASSERT(PCVAL_IS_SLOT(v)); return jsuint(v) >> 1; }
|
||||
inline jsuword SLOT_TO_PCVAL(jsuint i) { return (jsuword(i) << 1) | PCVAL_SLOT; }
|
||||
|
||||
inline bool PCVAL_IS_SPROP(jsuword v) { return PCVAL_TAG(v) == PCVAL_SPROP; }
|
||||
inline JSScopeProperty *PCVAL_TO_SPROP(jsuword v) { JS_ASSERT(PCVAL_IS_SPROP(v)); return (JSScopeProperty *) PCVAL_CLRTAG(v); }
|
||||
inline jsuword SPROP_TO_PCVAL(JSScopeProperty *sprop) { return PCVAL_SETTAG(jsuword(sprop), PCVAL_SPROP); }
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jspropertycache_h___ */
|
||||
|
@ -9145,7 +9145,7 @@ TraceRecorder::guardNativePropertyOp(JSObject* aobj, LIns* map_ins)
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2, jsuword& pcval)
|
||||
TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2, PCVal& pcval)
|
||||
{
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
JS_ASSERT(*pc != JSOP_INITPROP && *pc != JSOP_INITMETHOD &&
|
||||
@ -9223,8 +9223,8 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
||||
// the global it's assigning does not yet exist, create it.
|
||||
obj2 = obj;
|
||||
|
||||
// Use PCVAL_NULL to return "no such property" to our caller.
|
||||
pcval = PCVAL_NULL;
|
||||
// Use a null pcval to return "no such property" to our caller.
|
||||
pcval.setNull();
|
||||
return ARECORD_CONTINUE;
|
||||
}
|
||||
|
||||
@ -9250,7 +9250,7 @@ TraceRecorder::guardPropertyCacheHit(LIns* obj_ins,
|
||||
JSObject* aobj,
|
||||
JSObject* obj2,
|
||||
PropertyCacheEntry* entry,
|
||||
jsuword& pcval)
|
||||
PCVal& pcval)
|
||||
{
|
||||
VMSideExit* exit = snapshot(BRANCH_EXIT);
|
||||
|
||||
@ -11292,7 +11292,7 @@ TraceRecorder::setProp(jsval &l, PropertyCacheEntry* entry, JSScopeProperty* spr
|
||||
// Guard before anything else.
|
||||
LIns* map_ins = map(obj_ins);
|
||||
CHECK_STATUS(guardNativePropertyOp(obj, map_ins));
|
||||
jsuword pcval;
|
||||
PCVal pcval;
|
||||
CHECK_STATUS(guardPropertyCacheHit(obj_ins, map_ins, obj, obj2, entry, pcval));
|
||||
JS_ASSERT(scope->object == obj2);
|
||||
JS_ASSERT(scope->hasProperty(sprop));
|
||||
@ -12202,16 +12202,16 @@ TraceRecorder::record_JSOP_CALLNAME()
|
||||
|
||||
LIns* obj_ins = INS_CONSTOBJ(globalObj);
|
||||
JSObject* obj2;
|
||||
jsuword pcval;
|
||||
PCVal pcval;
|
||||
|
||||
CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval));
|
||||
|
||||
if (PCVAL_IS_NULL(pcval) || !PCVAL_IS_OBJECT(pcval))
|
||||
if (pcval.isNull() || !pcval.isObject())
|
||||
RETURN_STOP_A("callee is not an object");
|
||||
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(PCVAL_TO_OBJECT(pcval)));
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(pcval.toObject()));
|
||||
|
||||
stack(0, INS_CONSTOBJ(PCVAL_TO_OBJECT(pcval)));
|
||||
stack(0, INS_CONSTOBJ(pcval.toObject()));
|
||||
stack(1, obj_ins);
|
||||
return ARECORD_CONTINUE;
|
||||
}
|
||||
@ -12757,7 +12757,7 @@ TraceRecorder::name(jsval*& vp, LIns*& ins, NameResult& nr)
|
||||
uint32 slot;
|
||||
|
||||
JSObject* obj2;
|
||||
jsuword pcval;
|
||||
PCVal pcval;
|
||||
|
||||
/*
|
||||
* Property cache ensures that we are dealing with an existing property,
|
||||
@ -12766,7 +12766,7 @@ TraceRecorder::name(jsval*& vp, LIns*& ins, NameResult& nr)
|
||||
CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval));
|
||||
|
||||
/* Abort if property doesn't exist (interpreter will report an error.) */
|
||||
if (PCVAL_IS_NULL(pcval))
|
||||
if (pcval.isNull())
|
||||
RETURN_STOP_A("named property not found");
|
||||
|
||||
/* Insist on obj being the directly addressed object. */
|
||||
@ -12774,15 +12774,15 @@ TraceRecorder::name(jsval*& vp, LIns*& ins, NameResult& nr)
|
||||
RETURN_STOP_A("name() hit prototype chain");
|
||||
|
||||
/* Don't trace getter or setter calls, our caller wants a direct slot. */
|
||||
if (PCVAL_IS_SPROP(pcval)) {
|
||||
JSScopeProperty* sprop = PCVAL_TO_SPROP(pcval);
|
||||
if (pcval.isSprop()) {
|
||||
JSScopeProperty* sprop = pcval.toSprop();
|
||||
if (!isValidSlot(OBJ_SCOPE(obj), sprop))
|
||||
RETURN_STOP_A("name() not accessing a valid slot");
|
||||
slot = sprop->slot;
|
||||
} else {
|
||||
if (!PCVAL_IS_SLOT(pcval))
|
||||
if (!pcval.isSlot())
|
||||
RETURN_STOP_A("PCE is not a slot");
|
||||
slot = PCVAL_TO_SLOT(pcval);
|
||||
slot = pcval.toSlot();
|
||||
}
|
||||
|
||||
if (!lazilyImportGlobalSlot(slot))
|
||||
@ -12831,11 +12831,11 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp,
|
||||
* and guards the shape for us.
|
||||
*/
|
||||
JSObject* obj2;
|
||||
jsuword pcval;
|
||||
PCVal pcval;
|
||||
CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval));
|
||||
|
||||
/* Check for non-existent property reference, which results in undefined. */
|
||||
if (PCVAL_IS_NULL(pcval)) {
|
||||
if (pcval.isNull()) {
|
||||
if (slotp)
|
||||
RETURN_STOP_A("property not found");
|
||||
|
||||
@ -12876,7 +12876,7 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp,
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, jsuword pcval,
|
||||
TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, PCVal pcval,
|
||||
uint32 *slotp, LIns** v_insp, jsval *outp)
|
||||
{
|
||||
const JSCodeSpec& cs = js_CodeSpec[*cx->fp->regs->pc];
|
||||
@ -12887,8 +12887,8 @@ TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, jsuword pc
|
||||
uint32 slot;
|
||||
bool isMethod;
|
||||
|
||||
if (PCVAL_IS_SPROP(pcval)) {
|
||||
sprop = PCVAL_TO_SPROP(pcval);
|
||||
if (pcval.isSprop()) {
|
||||
sprop = pcval.toSprop();
|
||||
JS_ASSERT(OBJ_SCOPE(obj2)->hasProperty(sprop));
|
||||
|
||||
if (setflags && !sprop->hasDefaultSetter())
|
||||
@ -12910,9 +12910,9 @@ TraceRecorder::propTail(JSObject* obj, LIns* obj_ins, JSObject* obj2, jsuword pc
|
||||
isMethod = sprop->isMethod();
|
||||
JS_ASSERT_IF(isMethod, OBJ_SCOPE(obj2)->hasMethodBarrier());
|
||||
} else {
|
||||
if (!PCVAL_IS_SLOT(pcval))
|
||||
if (!pcval.isSlot())
|
||||
RETURN_STOP_A("PCE is not a slot");
|
||||
slot = PCVAL_TO_SLOT(pcval);
|
||||
slot = pcval.toSlot();
|
||||
sprop = NULL;
|
||||
isMethod = false;
|
||||
}
|
||||
@ -14606,27 +14606,27 @@ TraceRecorder::record_JSOP_CALLPROP()
|
||||
}
|
||||
|
||||
JSObject* obj2;
|
||||
jsuword pcval;
|
||||
PCVal pcval;
|
||||
CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval));
|
||||
|
||||
if (PCVAL_IS_OBJECT(pcval)) {
|
||||
if (PCVAL_IS_NULL(pcval))
|
||||
if (pcval.isObject()) {
|
||||
if (pcval.isNull())
|
||||
RETURN_STOP_A("callprop of missing method");
|
||||
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(PCVAL_TO_OBJECT(pcval)));
|
||||
JS_ASSERT(HAS_FUNCTION_CLASS(pcval.toObject()));
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(l)) {
|
||||
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, PCVAL_TO_OBJECT(pcval));
|
||||
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, pcval.toObject());
|
||||
if (!PRIMITIVE_THIS_TEST(fun, l))
|
||||
RETURN_STOP_A("callee does not accept primitive |this|");
|
||||
}
|
||||
|
||||
set(&l, INS_CONSTOBJ(PCVAL_TO_OBJECT(pcval)));
|
||||
set(&l, INS_CONSTOBJ(pcval.toObject()));
|
||||
} else {
|
||||
if (JSVAL_IS_PRIMITIVE(l))
|
||||
RETURN_STOP_A("callprop of primitive method");
|
||||
|
||||
JS_ASSERT_IF(PCVAL_IS_SPROP(pcval), !PCVAL_TO_SPROP(pcval)->isMethod());
|
||||
JS_ASSERT_IF(pcval.isSprop(), !pcval.toSprop()->isMethod());
|
||||
|
||||
AbortableRecordingStatus status = propTail(obj, obj_ins, obj2, pcval, NULL, NULL, &l);
|
||||
if (status != ARECORD_CONTINUE)
|
||||
|
@ -1208,7 +1208,7 @@ class TraceRecorder
|
||||
JS_REQUIRES_STACK bool map_is_native(JSObjectMap* map, nanojit::LIns* map_ins,
|
||||
nanojit::LIns*& ops_ins, size_t op_offset = 0);
|
||||
JS_REQUIRES_STACK AbortableRecordingStatus test_property_cache(JSObject* obj, nanojit::LIns* obj_ins,
|
||||
JSObject*& obj2, jsuword& pcval);
|
||||
JSObject*& obj2, PCVal& pcval);
|
||||
JS_REQUIRES_STACK RecordingStatus guardNativePropertyOp(JSObject* aobj,
|
||||
nanojit::LIns* map_ins);
|
||||
JS_REQUIRES_STACK RecordingStatus guardPropertyCacheHit(nanojit::LIns* obj_ins,
|
||||
@ -1216,7 +1216,7 @@ class TraceRecorder
|
||||
JSObject* aobj,
|
||||
JSObject* obj2,
|
||||
PropertyCacheEntry* entry,
|
||||
jsuword& pcval);
|
||||
PCVal& pcval);
|
||||
|
||||
void stobj_set_fslot(nanojit::LIns *obj_ins, unsigned slot,
|
||||
nanojit::LIns* v_ins);
|
||||
@ -1249,7 +1249,7 @@ class TraceRecorder
|
||||
uint32 *slotp, nanojit::LIns** v_insp,
|
||||
jsval* outp);
|
||||
JS_REQUIRES_STACK AbortableRecordingStatus propTail(JSObject* obj, nanojit::LIns* obj_ins,
|
||||
JSObject* obj2, jsuword pcval,
|
||||
JSObject* obj2, PCVal pcval,
|
||||
uint32 *slotp, nanojit::LIns** v_insp,
|
||||
jsval* outp);
|
||||
JS_REQUIRES_STACK RecordingStatus denseArrayElement(jsval& oval, jsval& idx, jsval*& vp,
|
||||
|
Loading…
Reference in New Issue
Block a user