[INFER] Don't clobber still-in-use FP registers during forgetKnownDouble, bug 617460.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 08 Dec 2010 08:10:39 -0800
changeset 74646 4d0b24613dd84a2a47ccc99b739cb28873aa1309
parent 74645 b6cef988a4c04d9e0f8bdd1fc8896652730251d0
child 74647 040fd88a48199bcafcafee8672e5f76752dd99ac
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs617460
milestone2.0b8pre
[INFER] Don't clobber still-in-use FP registers during forgetKnownDouble, bug 617460.
js/src/jit-test/tests/jaeger/bug617460.js
js/src/methodjit/FrameState.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug617460.js
@@ -0,0 +1,10 @@
+
+function f() {
+    var x = NaN;
+    if (2 > 0) {}
+    var y = {};
+    var z = (1234 - x);
+    y.foo = z;
+    assertEq(x, NaN);
+}
+f();
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -169,20 +169,23 @@ FrameState::entryName(FrameEntry *fe) co
 void
 FrameState::evictReg(AnyRegisterID reg)
 {
     FrameEntry *fe = regstate(reg).fe();
 
     JaegerSpew(JSpew_Regalloc, "evicting %s from %s\n", entryName(fe), reg.name());
 
     if (regstate(reg).type() == RematInfo::TYPE) {
-        ensureTypeSynced(fe, masm);
+        syncType(fe);
         fe->type.setMemory();
+    } else if (reg.isReg()) {
+        syncData(fe);
+        fe->data.setMemory();
     } else {
-        ensureDataSynced(fe, masm);
+        syncFe(fe);
         fe->data.setMemory();
     }
 }
 
 inline Lifetime *
 FrameState::variableLive(FrameEntry *fe, jsbytecode *pc) const
 {
     uint32 offset = pc - script->code;
@@ -2171,29 +2174,32 @@ FrameState::forgetKnownDouble(FrameEntry
 {
     /*
      * Forget all information indicating fe is a double, so we can use GPRs for its
      * contents.  We currently need to do this in order to use the entry in MICs/PICs
      * or to construct its ValueRemat. :FIXME: this needs to get fixed.
      */
     JS_ASSERT(!fe->isConstant() && fe->isType(JSVAL_TYPE_DOUBLE));
 
-    FPRegisterID fpreg = tempFPRegForData(fe);
-    forgetAllRegs(fe);
-    fe->resetUnsynced();
-
     RegisterID typeReg = allocReg();
     RegisterID dataReg = allocReg();
 
+    /* Copy into a different FP register, as breakDouble can modify fpreg. */
+    FPRegisterID fpreg = allocFPReg();
+    masm.moveDouble(tempFPRegForData(fe), fpreg);
     masm.breakDouble(fpreg, typeReg, dataReg);
 
+    forgetAllRegs(fe);
+    fe->resetUnsynced();
+
     regstate(typeReg).associate(fe, RematInfo::TYPE);
     regstate(dataReg).associate(fe, RematInfo::DATA);
     fe->type.setRegister(typeReg);
     fe->data.setRegister(dataReg);
+    freeReg(fpreg);
 }
 
 void
 FrameState::pinEntry(FrameEntry *fe, ValueRemat &vr)
 {
     if (fe->isConstant()) {
         vr = ValueRemat::FromConstant(fe->getValue());
     } else {