Bug 470133 - TM: fails to trace case with a type mismatch. r=gal

This commit is contained in:
Jeff Walden 2008-12-18 10:35:09 -08:00
Родитель 221bf7e84f
Коммит 5715a47f60
3 изменённых файлов: 52 добавлений и 27 удалений

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

@ -4540,7 +4540,7 @@ evalCmp(LOpcode op, JSString* l, JSString* r)
}
JS_REQUIRES_STACK void
TraceRecorder::strictEquality(bool equal)
TraceRecorder::strictEquality(bool equal, bool cmpCase)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
@ -4554,26 +4554,36 @@ TraceRecorder::strictEquality(bool equal)
}
LIns* x;
bool cond;
if (ltag == JSVAL_STRING) {
LIns* args[] = { r_ins, l_ins };
x = lir->ins2i(LIR_eq, lir->insCall(&js_EqualStrings_ci, args), equal);
cond = js_EqualStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r));
} else {
LOpcode op = (ltag != JSVAL_DOUBLE) ? LIR_eq : LIR_feq;
x = lir->ins2(op, l_ins, r_ins);
if (!equal)
x = lir->ins_eq0(x);
cond = (l == r);
}
cond = (cond == equal);
if (cmpCase) {
/* Only guard if the same path may not always be taken. */
if (!x->isconst())
guard(cond, x, BRANCH_EXIT);
return;
}
set(&l, x);
}
JS_REQUIRES_STACK bool
TraceRecorder::equality(int flags)
TraceRecorder::equality(bool negate, bool tryBranchAfterCond)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
LIns* x = NULL;
bool negate = !!(flags & CMP_NEGATE);
bool cond;
LIns* l_ins = get(&l);
LIns* r_ins = get(&r);
@ -4656,19 +4666,12 @@ TraceRecorder::equality(int flags)
}
}
if (flags & CMP_CASE) {
/* Only guard if the same path may not always be taken. */
if (!x->isconst())
guard(cond, x, BRANCH_EXIT);
return true;
}
/*
* Don't guard if the same path is always taken. If it isn't, we have to
* fuse comparisons and the following branch, because the interpreter does
* that.
*/
if ((flags & CMP_TRY_BRANCH_AFTER_COND) && !x->isconst())
if (tryBranchAfterCond && !x->isconst())
fuseIf(cx->fp->regs->pc + 1, cond, x);
/*
@ -4682,7 +4685,7 @@ TraceRecorder::equality(int flags)
}
JS_REQUIRES_STACK bool
TraceRecorder::relational(LOpcode op, int flags)
TraceRecorder::relational(LOpcode op, bool tryBranchAfterCond)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
@ -4788,7 +4791,7 @@ TraceRecorder::relational(LOpcode op, int flags)
* fuse comparisons and the following branch, because the interpreter does
* that.
*/
if ((flags & CMP_TRY_BRANCH_AFTER_COND) && !x->isconst())
if (tryBranchAfterCond && !x->isconst())
fuseIf(cx->fp->regs->pc + 1, cond, x);
/*
@ -5610,37 +5613,37 @@ TraceRecorder::record_JSOP_BITAND()
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_EQ()
{
return equality(CMP_TRY_BRANCH_AFTER_COND);
return equality(false, true);
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_NE()
{
return equality(CMP_NEGATE | CMP_TRY_BRANCH_AFTER_COND);
return equality(true, true);
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_LT()
{
return relational(LIR_flt, CMP_TRY_BRANCH_AFTER_COND);
return relational(LIR_flt, true);
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_LE()
{
return relational(LIR_fle, CMP_TRY_BRANCH_AFTER_COND);
return relational(LIR_fle, true);
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_GT()
{
return relational(LIR_fgt, CMP_TRY_BRANCH_AFTER_COND);
return relational(LIR_fgt, true);
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_GE()
{
return relational(LIR_fge, CMP_TRY_BRANCH_AFTER_COND);
return relational(LIR_fge, true);
}
JS_REQUIRES_STACK bool
@ -7085,14 +7088,14 @@ TraceRecorder::record_JSOP_LOOKUPSWITCH()
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_STRICTEQ()
{
strictEquality(true);
strictEquality(true, false);
return true;
}
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_STRICTNE()
{
strictEquality(false);
strictEquality(false, false);
return true;
}
@ -7591,7 +7594,8 @@ TraceRecorder::record_JSOP_CONDSWITCH()
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_CASE()
{
return equality(CMP_CASE);
strictEquality(true, true);
return true;
}
JS_REQUIRES_STACK bool
@ -7794,7 +7798,8 @@ TraceRecorder::record_JSOP_GOSUBX()
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_CASEX()
{
return equality(CMP_CASE);
strictEquality(true, true);
return true;
}
JS_REQUIRES_STACK bool

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

@ -355,10 +355,9 @@ class TraceRecorder : public avmplus::GCObject {
JS_REQUIRES_STACK bool incElem(jsint incr, bool pre = true);
JS_REQUIRES_STACK bool incName(jsint incr, bool pre = true);
enum { CMP_NEGATE = 1, CMP_TRY_BRANCH_AFTER_COND = 2, CMP_CASE = 4 };
JS_REQUIRES_STACK void strictEquality(bool equal);
JS_REQUIRES_STACK bool equality(int flags);
JS_REQUIRES_STACK bool relational(nanojit::LOpcode op, int flags);
JS_REQUIRES_STACK void strictEquality(bool equal, bool cmpCase);
JS_REQUIRES_STACK bool equality(bool negate, bool tryBranchAfterCond);
JS_REQUIRES_STACK bool relational(nanojit::LOpcode op, bool tryBranchAfterCond);
JS_REQUIRES_STACK bool unary(nanojit::LOpcode op);
JS_REQUIRES_STACK bool binary(nanojit::LOpcode op);

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

@ -3477,6 +3477,27 @@ function testComparisons()
testComparisons.expected = "no failures reported!";
test(testComparisons);
function testCaseAbort()
{
var four = "4";
var r = 0;
for (var i = 0; i < 5; i++)
{
switch (i)
{
case four: r += 1; break;
default: r += 2; break;
}
}
return "" + r;
}
testCaseAbort.expected = "10";
testCaseAbort.jitstats = {
recorderAborted: 0
};
test(testCaseAbort);
load("trace-test-math.js");
// BEGIN MANDELBROT STUFF