Don't clobber compared FP registers when syncing before a double comparison, bug 716119. r=dvander
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 13 Jan 2012 13:18:51 -0800
changeset 84437 2b2ca37b0305d1f41c42e26bd66b59bf0239e1b6
parent 84429 23099bd5d462e0fde1a316a2d9a512333eac912d
child 84438 21d52deaef00ae570639be613e9cc34fe7002840
push id21848
push usermak77@bonardo.net
push dateSat, 14 Jan 2012 09:02:20 +0000
treeherdermozilla-central@27a7f197c6fc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs716119
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Don't clobber compared FP registers when syncing before a double comparison, bug 716119. r=dvander
js/src/methodjit/FastArithmetic.cpp
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.cpp
js/src/methodjit/FrameState.h
--- a/js/src/methodjit/FastArithmetic.cpp
+++ b/js/src/methodjit/FastArithmetic.cpp
@@ -1427,23 +1427,34 @@ mjit::Compiler::jsop_relational_double(J
         frame.unpinReg(fpLeft);
 
     Assembler::DoubleCondition dblCond = DoubleCondForOp(op, fused);
 
     if (target) {
         stubcc.leave();
         OOL_STUBCALL(stub, REJOIN_BRANCH);
 
+        if (!allocateLeft)
+            frame.pinReg(fpLeft);
+        if (!allocateRight)
+            frame.pinReg(fpRight);
+
         frame.syncAndKillEverything();
+
         Jump j = masm.branchDouble(dblCond, fpLeft, fpRight);
 
         if (allocateLeft)
             frame.freeReg(fpLeft);
+        else
+            frame.unpinKilledReg(fpLeft);
+
         if (allocateRight)
             frame.freeReg(fpRight);
+        else
+            frame.unpinKilledReg(fpRight);
 
         frame.popn(2);
 
         Jump sj = stubcc.masm.branchTest32(GetStubCompareCondition(fused),
                                            Registers::ReturnReg, Registers::ReturnReg);
 
         /* Rejoin from the slow path. */
         stubcc.rejoin(Changes(0));
--- a/js/src/methodjit/FrameState-inl.h
+++ b/js/src/methodjit/FrameState-inl.h
@@ -1277,17 +1277,17 @@ FrameState::getCallee()
         addToTracker(fe);
         fe->resetSynced();
         fe->setType(JSVAL_TYPE_OBJECT);
     }
     return fe;
 }
 
 inline void
-FrameState::unpinKilledReg(RegisterID reg)
+FrameState::unpinKilledReg(AnyRegisterID reg)
 {
     regstate(reg).unpinUnsafe();
     freeRegs.putReg(reg);
 }
 
 inline void
 FrameState::forgetAllRegs(FrameEntry *fe)
 {
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -1493,20 +1493,21 @@ FrameState::syncAndKill(Registers kill, 
      */
     search = Registers(kill.freeMask & ~freeRegs.freeMask);
     while (!search.empty()) {
         AnyRegisterID reg = search.takeAnyReg();
         FrameEntry *fe = regstate(reg).usedBy();
         if (!fe || deadEntry(fe, ignore.nuses))
             continue;
 
-        JS_ASSERT(fe->isTracked() && !fe->isType(JSVAL_TYPE_DOUBLE));
+        JS_ASSERT(fe->isTracked());
 
         if (regstate(reg).type() == RematInfo::DATA) {
-            JS_ASSERT(fe->data.reg() == reg.reg());
+            JS_ASSERT_IF(reg.isFPReg(), fe->data.fpreg() == reg.fpreg());
+            JS_ASSERT_IF(!reg.isFPReg(), fe->data.reg() == reg.reg());
             JS_ASSERT(fe->data.synced());
             fe->data.setMemory();
         } else {
             JS_ASSERT(fe->type.reg() == reg.reg());
             JS_ASSERT(fe->type.synced());
             fe->type.setMemory();
         }
 
--- a/js/src/methodjit/FrameState.h
+++ b/js/src/methodjit/FrameState.h
@@ -801,17 +801,17 @@ class FrameState
     /*
      * Unpins a previously pinned register.
      */
     inline void unpinReg(AnyRegisterID reg) { regstate(reg).unpin(); }
 
     /*
      * Same as unpinReg(), but does not restore the FrameEntry.
      */
-    inline void unpinKilledReg(RegisterID reg);
+    inline void unpinKilledReg(AnyRegisterID reg);
 
     /* Pins a data or type register if one exists. */
     MaybeRegisterID maybePinData(FrameEntry *fe);
     MaybeRegisterID maybePinType(FrameEntry *fe);
     void maybeUnpinReg(MaybeRegisterID reg);
 
     /*
      * Dups the top item on the stack.