зеркало из https://github.com/mozilla/gecko-dev.git
Bug 487561 - More cleanup from bug 452498 and bug 487271 patches (r=mrbkap/igor, and this fixes bug 487570).
This commit is contained in:
Родитель
af8d90fa33
Коммит
35a98e12e5
|
@ -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,13 +729,21 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
struct JSObjectBox {
|
||||
JSObjectBox *traceLink;
|
||||
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче