Bug 487561 - More cleanup from bug 452498 and bug 487271 patches (r=mrbkap/igor, and this fixes bug 487570).

This commit is contained in:
Brendan Eich 2009-04-09 15:05:12 -07:00
Родитель af8d90fa33
Коммит 35a98e12e5
2 изменённых файлов: 88 добавлений и 58 удалений

Просмотреть файл

@ -2490,6 +2490,80 @@ JS_STATIC_ASSERT(!CAN_DO_FAST_INC_DEC(INT_TO_JSVAL(JSVAL_INT_MAX)));
# endif
#endif
/*
* Deadlocks or else bad races are likely if JS_THREADSAFE, so we must rely on
* single-thread DEBUG js shell testing to verify property cache hits.
*/
#if defined DEBUG && !defined JS_THREADSAFE
# define ASSERT_VALID_PROPERTY_CACHE_HIT(pcoff,obj,pobj,entry) \
JS_BEGIN_MACRO \
if (!AssertValidPropertyCacheHit(cx, script, regs, pcoff, obj, pobj, \
entry)) { \
goto error; \
} \
JS_END_MACRO
static bool
AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, JSFrameRegs& regs,
ptrdiff_t pcoff, JSObject *start, JSObject *found,
JSPropCacheEntry *entry)
{
uint32 sample = cx->runtime->gcNumber;
JSAtom *atom;
if (pcoff >= 0)
GET_ATOM_FROM_BYTECODE(script, regs.pc, pcoff, atom);
else
atom = cx->runtime->atomState.lengthAtom;
JSObject *obj, *pobj;
JSProperty *prop;
bool ok;
if (JOF_OPMODE(*regs.pc) == JOF_NAME) {
ok = js_FindProperty(cx, ATOM_TO_JSID(atom), &obj, &pobj, &prop);
} else {
obj = start;
ok = js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop);
}
if (!ok)
return false;
if (!prop)
return true;
if (cx->runtime->gcNumber != sample ||
PCVCAP_SHAPE(entry->vcap) != OBJ_SHAPE(pobj)) {
OBJ_DROP_PROPERTY(cx, pobj, prop);
return true;
}
JS_ASSERT(prop);
JS_ASSERT(pobj == found);
JSScopeProperty *sprop = (JSScopeProperty *) prop;
if (PCVAL_IS_SLOT(entry->vword)) {
JS_ASSERT(PCVAL_TO_SLOT(entry->vword) == sprop->slot);
} else if (PCVAL_IS_SPROP(entry->vword)) {
JS_ASSERT(PCVAL_TO_SPROP(entry->vword) == sprop);
} else {
jsval v;
JS_ASSERT(PCVAL_IS_OBJECT(entry->vword));
JS_ASSERT(entry->vword != PCVAL_NULL);
JS_ASSERT(SCOPE_IS_BRANDED(OBJ_SCOPE(pobj)));
JS_ASSERT(SPROP_HAS_STUB_GETTER(sprop));
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));
}
OBJ_DROP_PROPERTY(cx, pobj, prop);
return true;
}
#else
# define ASSERT_VALID_PROPERTY_CACHE_HIT(pcoff,obj,pobj,entry) ((void) 0)
#endif
/*
* Ensure that the intrepreter switch can close call-bytecode cases in the
* same way as non-call bytecodes.
@ -3473,58 +3547,6 @@ js_Interpret(JSContext *cx)
} \
JS_END_MACRO
/*
* Deadlocks or else bad races are likely if JS_THREADSAFE, so we must rely on
* single-thread DEBUG js shell testing to verify property cache hits.
*/
#if defined DEBUG && !defined JS_THREADSAFE
# define ASSERT_VALID_PROPERTY_CACHE_HIT(pcoff,obj,pobj,entry) \
do { \
JSAtom *atom_; \
JSObject *obj_, *pobj_; \
JSProperty *prop_; \
JSScopeProperty *sprop_; \
uint32 sample_ = rt->gcNumber; \
if (pcoff >= 0) \
GET_ATOM_FROM_BYTECODE(script, regs.pc, pcoff, atom_); \
else \
atom_ = rt->atomState.lengthAtom; \
if (JOF_OPMODE(op) == JOF_NAME) { \
ok = js_FindProperty(cx, ATOM_TO_JSID(atom_), &obj_, &pobj_, \
&prop_); \
} else { \
obj_ = obj; \
ok = js_LookupProperty(cx, obj, ATOM_TO_JSID(atom_), &pobj_, \
&prop_); \
} \
if (!ok) \
goto error; \
if (rt->gcNumber != sample_) \
break; \
JS_ASSERT(prop_); \
JS_ASSERT(pobj_ == pobj); \
sprop_ = (JSScopeProperty *) prop_; \
if (PCVAL_IS_SLOT(entry->vword)) { \
JS_ASSERT(PCVAL_TO_SLOT(entry->vword) == sprop_->slot); \
} else if (PCVAL_IS_SPROP(entry->vword)) { \
JS_ASSERT(PCVAL_TO_SPROP(entry->vword) == sprop_); \
} else { \
jsval v_; \
JS_ASSERT(PCVAL_IS_OBJECT(entry->vword)); \
JS_ASSERT(entry->vword != PCVAL_NULL); \
JS_ASSERT(SCOPE_IS_BRANDED(OBJ_SCOPE(pobj))); \
JS_ASSERT(SPROP_HAS_STUB_GETTER(sprop_)); \
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_)); \
} \
OBJ_DROP_PROPERTY(cx, pobj_, prop_); \
} while (0)
#else
# define ASSERT_VALID_PROPERTY_CACHE_HIT(pcoff,obj,pobj,entry) ((void) 0)
#endif
/*
* Skip the JSOP_POP typically found after a JSOP_SET* opcode, where oplen is
* the constant length of the SET opcode sequence, and spdec is the constant

Просмотреть файл

@ -729,12 +729,20 @@ JSParseNode::isFunArg() const
inline void
JSParseNode::setFunArg()
{
if (pn_defn) {
((JSDefinition *)this)->pn_dflags |= PND_FUNARG;
} else if (pn_used) {
/*
* pn_defn NAND pn_used must be true, per this chart:
*
* pn_defn pn_used
* 0 0 anonymous function used implicitly, e.g. by
* hidden yield in a genexp
* 0 1 a use of a definition or placeholder
* 1 0 a definition or placeholder
* 1 1 error: this case must not be possible
*/
JS_ASSERT(!(pn_defn & pn_used));
if (pn_used)
pn_lexdef->pn_dflags |= PND_FUNARG;
pn_dflags |= PND_FUNARG;
}
pn_dflags |= PND_FUNARG;
}
struct JSObjectBox {
@ -784,7 +792,7 @@ struct JSFunctionBoxQueue {
JSFunctionBox *pull() {
if (tail == head)
return NULL;
JS_ASSERT(tail != head);
JS_ASSERT(tail < head);
JSFunctionBox *funbox = vector[tail++ & lengthMask];
funbox->queued = false;
return funbox;