If we see a f2i(UnboxDouble) chain, simplify it to UnboxInt32 which does the conversion internally. This also enables a fastpath to read 31-bit jsval integers from arrays.
If we see a f2i(UnboxDouble) chain, simplify it to UnboxInt32 which does the conversion internally. This also enables a fastpath to read 31-bit jsval integers from arrays.
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -106,20 +106,17 @@ jsdouble FASTCALL builtin_UnboxDouble(js
return (jsdouble)JSVAL_TO_INT(v);
return *JSVAL_TO_DOUBLE(v);
}
jsint FASTCALL builtin_UnboxInt32(jsval v)
{
if (JS_LIKELY(JSVAL_IS_INT(v)))
return JSVAL_TO_INT(v);
- jsint i;
- if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_INT(*JSVAL_TO_DOUBLE(v), i))
- return i;
- return INT32_ERROR_COOKIE;
+ return js_DoubleToECMAInt32(*JSVAL_TO_DOUBLE(v));
}
int32 FASTCALL builtin_doubleToInt32(jsdouble d)
{
return js_DoubleToECMAInt32(d);
}
int32 FASTCALL builtin_doubleToUint32(jsdouble d)
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -348,16 +348,20 @@ public:
if (isPromote(lhs) && isPromote(rhs)) {
LOpcode op = LOpcode(s0->opcode() & ~LIR64);
return out->ins2(op, demote(out, lhs), demote(out, rhs));
}
}
if (s0->isop(LIR_i2f) || s0->isop(LIR_u2f)) {
return s0->oprnd1();
}
+ if (s0->isCall() && s0->fid() == F_UnboxDouble) {
+ LIns* args2[] = { callArgN(s0, 0) };
+ return out->insCall(F_UnboxInt32, args2);
+ }
break;
case F_BoxDouble:
JS_ASSERT(s0->isQuad());
if (s0->isop(LIR_i2f)) {
LIns* args2[] = { s0->oprnd1(), args[1] };
return out->insCall(F_BoxInt32, args2);
}
break;
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -290,11 +290,20 @@ function trees() {
if ((i & 1) == 0) o[0]++;
else if ((i & 2) == 0) o[1]++;
else o[2]++;
}
return o;
}
test("trees", trees(), "50,25,25");
+function unboxint() {
+ var q = 0;
+ var o = [4];
+ for (var i = 0; i < 100; ++i)
+ q = o[0] << 1;
+ return q;
+}
+test("unboxint", unboxint(), "8");
+
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
print("pass:", passes.length ? passes.join(",") : "<none>");
print("FAIL:", fails.length ? fails.join(",") : "<none>");