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.
authorAndreas Gal <gal@mozilla.com>
Sun, 27 Jul 2008 14:55:26 -0700
changeset 17847 7d4d4ed0e52e04cc090ac789e3f09a41a0295fc8
parent 17846 ed83a368ff1974b06acb1e3315b58c9309919bf6
child 17848 980c23ed651ebe7dc13570c42655484296353303
child 17849 0d41393d023b84be41a9449f73f5ccad7d9bcfc9
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1a1pre
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.
js/src/jsbuiltins.cpp
js/src/jstracer.cpp
js/src/trace-test.js
--- 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>");