mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Don't guard on constant decisions, which will always have the same path (bug 452884, r=gal).
This commit is contained in:
parent
b15e1fe4d3
commit
09123ebd63
@ -367,6 +367,11 @@ static bool isconst(LIns* i, int32_t c)
|
||||
return i->isconst() && i->constval() == c;
|
||||
}
|
||||
|
||||
static bool isAnyConst(LIns* i)
|
||||
{
|
||||
return i->isconst() || i->isconstq();
|
||||
}
|
||||
|
||||
static bool overflowSafe(LIns* i)
|
||||
{
|
||||
LIns* c;
|
||||
@ -2790,9 +2795,15 @@ TraceRecorder::ifop()
|
||||
jsdouble d = asNumber(v);
|
||||
jsdpun u;
|
||||
u.d = 0;
|
||||
guard(d == 0 || JSDOUBLE_IS_NaN(d),
|
||||
lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64)),
|
||||
BRANCH_EXIT);
|
||||
LIns* v_ins = get(&v);
|
||||
// Only insert the guard if the condition is not constant, since in
|
||||
// that case at runtime we would always take the same path as the
|
||||
// interpreter is taking right now and hence there is no need for
|
||||
// a guard.
|
||||
if (!v_ins->isconst() && !v_ins->isconstq())
|
||||
guard(d == 0 || JSDOUBLE_IS_NaN(d),
|
||||
lir->ins2(LIR_feq, v_ins, lir->insImmq(u.u64)),
|
||||
BRANCH_EXIT);
|
||||
} else if (JSVAL_IS_STRING(v)) {
|
||||
guard(JSSTRING_LENGTH(JSVAL_TO_STRING(v)) == 0,
|
||||
lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
@ -2924,9 +2935,16 @@ TraceRecorder::cmp(LOpcode op, int flags)
|
||||
LIns* x;
|
||||
bool negate = !!(flags & CMP_NEGATE);
|
||||
bool cond;
|
||||
LIns* l_ins = get(&l);
|
||||
LIns* r_ins = get(&r);
|
||||
|
||||
/* Don't guard if the same path is always taken. */
|
||||
if (isAnyConst(r_ins) && isAnyConst(l_ins))
|
||||
return true;
|
||||
|
||||
if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
|
||||
JS_ASSERT(!negate);
|
||||
LIns* args[] = { get(&r), get(&l) };
|
||||
LIns* args[] = { r_ins, l_ins };
|
||||
x = lir->ins1(LIR_i2f, lir->insCall(F_CompareStrings, args));
|
||||
x = lir->ins2i(op, x, 0);
|
||||
jsint result = js_CompareStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r));
|
||||
@ -2952,8 +2970,6 @@ TraceRecorder::cmp(LOpcode op, int flags)
|
||||
JSAutoTempValueRooter tvr(cx, 2, tmp);
|
||||
|
||||
// TODO: coerce non-numbers to numbers if it's not string-on-string above
|
||||
LIns* l_ins = get(&l);
|
||||
LIns* r_ins = get(&r);
|
||||
jsdouble lnum;
|
||||
jsdouble rnum;
|
||||
LIns* args[] = { l_ins, cx_ins };
|
||||
@ -2973,7 +2989,7 @@ TraceRecorder::cmp(LOpcode op, int flags)
|
||||
}
|
||||
lnum = js_ValueToNumber(cx, &tmp[0]);
|
||||
|
||||
args[0] = get(&r);
|
||||
args[0] = r_ins;
|
||||
args[1] = cx_ins;
|
||||
if (JSVAL_IS_STRING(r)) {
|
||||
r_ins = lir->insCall(F_StringToNumber, args);
|
||||
@ -3065,8 +3081,16 @@ TraceRecorder::equal(int flags)
|
||||
jsval& r = stackval(-1);
|
||||
jsval& l = stackval(-2);
|
||||
bool negate = !!(flags & CMP_NEGATE);
|
||||
|
||||
LIns* r_ins = get(&r);
|
||||
LIns* l_ins = get(&l);
|
||||
|
||||
/* Don't guard if the same path is always taken. */
|
||||
if (isAnyConst(r_ins) && isAnyConst(l_ins))
|
||||
return true;
|
||||
|
||||
if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
|
||||
LIns* args[] = { get(&r), get(&l) };
|
||||
LIns* args[] = { r_ins, l_ins };
|
||||
bool cond = js_EqualStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r)) ^ negate;
|
||||
LIns* x = lir->ins_eq0(lir->insCall(F_EqualStrings, args));
|
||||
if (!negate)
|
||||
@ -3092,7 +3116,7 @@ TraceRecorder::equal(int flags)
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(l) && JSVAL_IS_OBJECT(r)) {
|
||||
bool cond = (l == r) ^ negate;
|
||||
LIns* x = lir->ins2(LIR_eq, get(&l), get(&r));
|
||||
LIns* x = lir->ins2(LIR_eq, l_ins, r_ins);
|
||||
if (negate)
|
||||
x = lir->ins_eq0(x);
|
||||
|
||||
|
@ -1185,6 +1185,22 @@ function testNegZero2() {
|
||||
}
|
||||
testNegZero2();
|
||||
|
||||
function testConstSwitch() {
|
||||
var x;
|
||||
for (var j=0;j<5;++j) { switch(1.1) { case NaN: case 2: } x = 2; }
|
||||
return x;
|
||||
}
|
||||
testConstSwitch.expected = 2;
|
||||
test(testConstSwitch);
|
||||
|
||||
function testConstIf() {
|
||||
var x;
|
||||
for (var j=0;j<5;++j) { if (1.1 || 5) { } x = 2;}
|
||||
return x;
|
||||
}
|
||||
testConstIf.expected = 2;
|
||||
test(testConstIf);
|
||||
|
||||
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
|
||||
print("\npassed:", passes.length && passes.join(","));
|
||||
print("\nFAILED:", fails.length && fails.join(","));
|
||||
|
Loading…
Reference in New Issue
Block a user