[INFER] Don't convert int32 entries to doubles during storeTop, bug 639808.
authorBrian Hackett <bhackett1024@gmail.com>
Tue, 08 Mar 2011 19:36:59 -0800
changeset 74738 f2fdb87d75a358ad7902e841ba95dd4a0e92dc2a
parent 74737 adc45b0a01c8c5b9f56e2fcc237ae101aaba27c0
child 74739 03819499ac0278101208bcd4f5848e516794d399
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs639808
milestone2.0b12pre
[INFER] Don't convert int32 entries to doubles during storeTop, bug 639808.
js/src/jit-test/tests/jaeger/bug639808.js
js/src/methodjit/FrameState.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug639808.js
@@ -0,0 +1,7 @@
+function f() {
+    var x = 1.23;
+    var y = [].length;
+    x = ++y;
+    y - 1;
+}
+f();
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -2106,41 +2106,39 @@ FrameState::storeTop(FrameEntry *target,
         if (type == JSVAL_TYPE_UNKNOWN) {
             if (backing->isTypeKnown()) {
                 target->setType(backing->getKnownType(), backing->getTypeSet());
             } else {
                 RegisterID reg = tempRegForType(backing);
                 target->type.setRegister(reg);
                 regstate(reg).reassociate(target);
             }
-        } else if (type == JSVAL_TYPE_DOUBLE) {
+        } else if (type != JSVAL_TYPE_DOUBLE || backing->isType(JSVAL_TYPE_INT32)) {
+            /*
+             * Treat the stored entry as an int even if inference has marked it
+             * as a float (we will fixDoubles on it before branching), to avoid
+             * demoting the backing.
+             */
+            if (type == JSVAL_TYPE_DOUBLE)
+                type = JSVAL_TYPE_INT32;
+            JS_ASSERT_IF(backing->isTypeKnown(), backing->isType(type));
+            if (!backing->isTypeKnown())
+                learnType(backing, type);
+            target->setType(type, typeSet);
+        } else {
             FPRegisterID fpreg = allocFPReg();
-            if (backing->isTypeKnown()) {
-                JS_ASSERT(backing->isType(JSVAL_TYPE_INT32));
-                masm.convertInt32ToDouble(reg, fpreg);
-            } else {
-                syncFe(backing);
-                masm.moveInt32OrDouble(addressOf(backing), fpreg);
-            }
+            syncFe(backing);
+            masm.moveInt32OrDouble(addressOf(backing), fpreg);
 
             forgetAllRegs(backing);
 
             backing->setType(JSVAL_TYPE_DOUBLE, NULL);
             target->setType(JSVAL_TYPE_DOUBLE, NULL);
             target->data.setFPRegister(fpreg);
             regstate(fpreg).associate(target, RematInfo::DATA);
-        } else {
-            /*
-             * The backing should normally already be the type we are storing.  However,
-             * we do not always keep track of the type in fused opcodes like GETTHISPROP.
-             */
-            JS_ASSERT_IF(backing->isTypeKnown(), backing->isType(type));
-            if (!backing->isTypeKnown())
-                learnType(backing, type);
-            target->setType(type, typeSet);
         }
     }
 
     if (!backing->isTypeKnown())
         backing->type.invalidate();
     backing->data.invalidate();
     backing->setCopyOf(target);