Make guard return expected, so we can trace alternate cases easily.

Better diagnostic for non-global scope chain head.
This commit is contained in:
shaver@mozilla.org 2008-07-30 22:59:13 -07:00
parent 3f1c0f5bbe
commit b3bbda75fa
2 changed files with 26 additions and 28 deletions

View File

@ -1018,12 +1018,11 @@ TraceRecorder::snapshot(ExitType exitType)
}
/* Emit a guard for condition (cond), expecting to evaluate to boolean result (expected). */
LIns*
bool
TraceRecorder::guard(bool expected, LIns* cond, ExitType exitType)
{
return lir->insGuard(expected ? LIR_xf : LIR_xt,
cond,
snapshot(exitType));
lir->insGuard(expected ? LIR_xf : LIR_xt, cond, snapshot(exitType));
return expected;
}
/* Try to match the type of a slot to type t. checkType is used to verify that the type of
@ -2016,23 +2015,20 @@ bool TraceRecorder::guardDenseArray(JSObject* obj, LIns* obj_ins)
bool TraceRecorder::guardDenseArrayIndex(JSObject* obj, jsint idx, LIns* obj_ins,
LIns* dslots_ins, LIns* idx_ins)
{
jsuint length = ARRAY_DENSE_LENGTH(obj);
if (!((jsuint)idx < length && idx < obj->fslots[JSSLOT_ARRAY_LENGTH]))
return false;
jsuint capacity = ARRAY_DENSE_LENGTH(obj);
jsuint length = obj->fslots[JSSLOT_ARRAY_LENGTH];
LIns* length_ins = stobj_get_fslot(obj_ins, JSSLOT_ARRAY_LENGTH);
// guard(index >= 0)
guard(true, lir->ins2i(LIR_ge, idx_ins, 0));
// guard(index < length)
guard(true, lir->ins2(LIR_lt, idx_ins, length_ins));
// guard(index < capacity)
guard(false, lir->ins_eq0(dslots_ins));
guard(true, lir->ins2(LIR_lt, idx_ins,
lir->insLoadi(dslots_ins, 0 - sizeof(jsval))));
return true;
return guard(idx < (jsint)length, lir->ins2(LIR_lt, idx_ins, length_ins), BRANCH_EXIT) &&
// guard(index >= 0)
guard(idx >= 0, lir->ins2i(LIR_ge, idx_ins, 0), BRANCH_EXIT) &&
// guard(capacity)
guard(capacity != 0, lir->ins_eq0(dslots_ins), BRANCH_EXIT) &&
// guard(index < capacity)
guard(idx < (jsint)capacity, lir->ins2(LIR_lt, idx_ins,
lir->insLoadi(dslots_ins, 0 - sizeof(jsval))));
}
void
@ -2769,16 +2765,19 @@ TraceRecorder::elem(jsval& l, jsval& r, jsval*& vp, LIns*& v_ins, LIns*& addr_in
guard(true, lir->ins2(LIR_feq, get(&r), lir->ins1(LIR_i2f, idx_ins)));
LIns* dslots_ins = lir->insLoadi(obj_ins, offsetof(JSObject, dslots));
if (!guardDenseArrayIndex(obj, idx, obj_ins, dslots_ins, idx_ins))
return false;
vp = &obj->dslots[idx];
if (guardDenseArrayIndex(obj, idx, obj_ins, dslots_ins, idx_ins)) {
vp = &obj->dslots[idx];
addr_ins = lir->ins2(LIR_add, dslots_ins,
lir->ins2i(LIR_lsh, idx_ins, (sizeof(jsval) == 4) ? 2 : 3));
addr_ins = lir->ins2(LIR_add, dslots_ins,
lir->ins2i(LIR_lsh, idx_ins, (sizeof(jsval) == 4) ? 2 : 3));
/* load the value, check the type (need to check JSVAL_HOLE only for booleans) */
v_ins = lir->insLoad(LIR_ld, addr_ins, 0);
return unbox_jsval(*vp, v_ins);
}
/* load the value, check the type (need to check JSVAL_HOLE only for booleans) */
v_ins = lir->insLoad(LIR_ld, addr_ins, 0);
return unbox_jsval(*vp, v_ins);
v_ins = lir->insImm(JSVAL_TO_BOOLEAN(JSVAL_VOID));
return true;
}
bool
@ -2808,7 +2807,7 @@ bool TraceRecorder::record_JSOP_NAME()
{
JSObject* obj = cx->fp->scopeChain;
if (obj != globalObj)
return false;
ABORT_TRACE("scope chain is not global");
LIns* obj_ins = lir->insLoadi(lir->insLoadi(cx_ins, offsetof(JSContext, fp)),
offsetof(JSStackFrame, scopeChain));

View File

@ -188,8 +188,7 @@ class TraceRecorder {
bool lazilyImportGlobalSlot(unsigned slot);
unsigned getCallDepth() const;
nanojit::LIns* guard(bool expected, nanojit::LIns* cond,
nanojit::ExitType exitType = nanojit::DONT_GROW);
bool guard(bool expected, nanojit::LIns* cond, nanojit::ExitType exitType = nanojit::DONT_GROW);
nanojit::LIns* addName(nanojit::LIns* ins, const char* name);
nanojit::LIns* get(jsval* p);