[INFER] Don't use loop registers for entries after coercing them to double/any for a branch, bug 682563.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 29 Aug 2011 13:59:06 -0700
changeset 76160 40d6de723ea80b2f558eac8d0df45c5704ef3aea
parent 76159 05363eda1c9a50a689cec3d8fc4e34c430745940
child 76161 cbda722273a9c8f56c68d045ce3e28fc8f4fda70
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
bugs682563
milestone9.0a1
[INFER] Don't use loop registers for entries after coercing them to double/any for a branch, bug 682563.
js/src/methodjit/Compiler.cpp
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.h
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -6913,30 +6913,32 @@ mjit::Compiler::fixDoubleTypes(jsbytecod
             JS_ASSERT(newv->slot < TotalSlots(script));
             types::TypeSet *targetTypes = analysis->getValueTypes(newv->value);
             FrameEntry *fe = frame.getSlotEntry(newv->slot);
             VarType &vt = a->varTypes[newv->slot];
             if (targetTypes->getKnownTypeTag(cx) == JSVAL_TYPE_DOUBLE) {
                 if (vt.type == JSVAL_TYPE_INT32) {
                     fixedIntToDoubleEntries.append(newv->slot);
                     frame.ensureDouble(fe);
+                    frame.forgetLoopReg(fe);
                 } else if (vt.type == JSVAL_TYPE_UNKNOWN) {
                     /*
                      * Unknown here but a double at the target. The type
                      * set for the existing value must be empty, so this
                      * code is doomed and we can just mark the value as
                      * a double.
                      */
                     frame.ensureDouble(fe);
                 } else {
                     JS_ASSERT(vt.type == JSVAL_TYPE_DOUBLE);
                 }
             } else if (fe->isType(JSVAL_TYPE_DOUBLE)) {
                 fixedDoubleToAnyEntries.append(newv->slot);
                 frame.syncAndForgetFe(fe);
+                frame.forgetLoopReg(fe);
             }
             newv++;
         }
     }
 }
 
 void
 mjit::Compiler::watchGlobalReallocation()
--- a/js/src/methodjit/FrameState-inl.h
+++ b/js/src/methodjit/FrameState-inl.h
@@ -874,16 +874,27 @@ FrameState::syncAndForgetFe(FrameEntry *
 
     syncFe(fe);
     forgetAllRegs(fe);
     fe->type.setMemory();
     fe->data.setMemory();
 }
 
 inline void
+FrameState::forgetLoopReg(FrameEntry *fe)
+{
+    /*
+     * Don't use a loop register for fe in the active loop, as its underlying
+     * representation may have changed since the start of the loop.
+     */
+    if (loop)
+        fe->lastLoop = loop->headOffset();
+}
+
+inline void
 FrameState::syncType(FrameEntry *fe)
 {
     JS_ASSERT(!fe->isType(JSVAL_TYPE_DOUBLE));
 
     FrameEntry *backing = fe;
     if (fe->isCopy())
         backing = fe->copyOf();
 
--- a/js/src/methodjit/FrameState.h
+++ b/js/src/methodjit/FrameState.h
@@ -946,16 +946,17 @@ class FrameState
     uint32 allocTemporary();  /* -1 if limit reached. */
     void clearTemporaries();
     inline FrameEntry *getTemporary(uint32 which);
 
     /* Return NULL or a new vector with all current copies of temporaries. */
     Vector<TemporaryCopy> *getTemporaryCopies();
 
     inline void syncAndForgetFe(FrameEntry *fe, bool markSynced = false);
+    inline void forgetLoopReg(FrameEntry *fe);
 
   private:
     inline AnyRegisterID allocAndLoadReg(FrameEntry *fe, bool fp, RematInfo::RematType type);
     inline void forgetReg(AnyRegisterID reg);
     AnyRegisterID evictSomeReg(uint32 mask);
     void evictReg(AnyRegisterID reg);
     inline FrameEntry *rawPush();
     inline void addToTracker(FrameEntry *fe);