Fix rsh, storeTo() allocReg() usage. b=596817, r=dvander.
authorSean Stangl <sstangl@mozilla.com>
Tue, 28 Sep 2010 20:06:12 -0400
changeset 54751 32c14e640a89c2e163aefbce14742fae8e5f30da
parent 54750 49890751e2558589f395c99ce9c7091c9b4f1f84
child 54752 b91d6314aaae5da11ab5405a785abbda5435ecae
push id16011
push userrsayre@mozilla.com
push dateWed, 29 Sep 2010 06:01:57 +0000
treeherdermozilla-central@d7e659b4f80c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs596817
milestone2.0b7pre
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
Fix rsh, storeTo() allocReg() usage. b=596817, r=dvander.
js/src/methodjit/FastOps.cpp
js/src/methodjit/FrameState.cpp
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -201,34 +201,36 @@ mjit::Compiler::jsop_rsh_unknown_any(Fra
     RegisterID rhsData = rightRegForShift(rhs);
 
     MaybeRegisterID rhsType;
     if (!rhs->isTypeKnown()) {
         rhsType.setReg(frame.tempRegForType(rhs));
         frame.pinReg(rhsType.reg());
     }
 
-    RegisterID lhsType = frame.tempRegForType(lhs);
-    frame.pinReg(lhsType);
     RegisterID lhsData = frame.copyDataIntoReg(lhs);
-    frame.unpinReg(lhsType);
+    MaybeRegisterID lhsType;
+    if (rhsType.isSet() && frame.haveSameBacking(lhs, rhs))
+        lhsType = rhsType;
+    else
+        lhsType = frame.tempRegForType(lhs);
 
     /* Non-integer rhs jumps to stub. */
     MaybeJump rhsIntGuard;
     if (rhsType.isSet()) {
         rhsIntGuard.setJump(masm.testInt32(Assembler::NotEqual, rhsType.reg()));
         frame.unpinReg(rhsType.reg());
     }
 
     /* Non-integer lhs jumps to double guard. */
-    Jump lhsIntGuard = masm.testInt32(Assembler::NotEqual, lhsType);
+    Jump lhsIntGuard = masm.testInt32(Assembler::NotEqual, lhsType.reg());
     stubcc.linkExitDirect(lhsIntGuard, stubcc.masm.label());
 
     /* Attempt to convert lhs double to int32. */
-    Jump lhsDoubleGuard = stubcc.masm.testDouble(Assembler::NotEqual, lhsType);
+    Jump lhsDoubleGuard = stubcc.masm.testDouble(Assembler::NotEqual, lhsType.reg());
     frame.loadDouble(lhs, FPRegisters::First, stubcc.masm);
     Jump lhsTruncateGuard = stubcc.masm.branchTruncateDoubleToInt32(FPRegisters::First, lhsData);
     stubcc.crossJump(stubcc.masm.jump(), masm.label());
 
     lhsDoubleGuard.linkTo(stubcc.masm.label(), &stubcc.masm);
     lhsTruncateGuard.linkTo(stubcc.masm.label(), &stubcc.masm);
 
     if (rhsIntGuard.isSet())
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -238,46 +238,62 @@ FrameState::storeTo(FrameEntry *fe, Addr
     if (fe->type.inMemory() && fe->data.inMemory()) {
         /* Future optimization: track that the Value is in a register. */
         RegisterID vreg = Registers::ValueReg;
         masm.loadPtr(addressOf(fe), vreg);
         masm.storePtr(vreg, address);
         return;
     }
 
-    /* Get a register for the payload. */
+    /*
+     * If dreg is obtained via allocReg(), then calling
+     * pinReg() trips an assertion. But in all other cases,
+     * calling pinReg() is necessary in the fe->type.inMemory() path.
+     * Remember whether pinReg() can be safely called.
+     */
+    bool canPinDreg = true;
     bool wasInRegister = fe->data.inRegister();
+
+    /* Get a register for the payload. */
     MaybeRegisterID dreg;
-
     if (fe->data.inRegister()) {
         dreg = fe->data.reg();
     } else {
         JS_ASSERT(fe->data.inMemory());
-        dreg = popped ? allocReg() : allocReg(fe, RematInfo::DATA);
+        if (popped) {
+            dreg = allocReg();
+            canPinDreg = false;
+        } else {
+            dreg = allocReg(fe, RematInfo::DATA);
+            fe->data.setRegister(dreg.reg());
+        }
         masm.loadPayload(addressOf(fe), dreg.reg());
-        if (!popped)
-            fe->data.setRegister(dreg.reg());
     }
     
     /* Store the Value. */
     if (fe->type.inRegister()) {
         masm.storeValueFromComponents(fe->type.reg(), dreg.reg(), address);
     } else if (fe->isTypeKnown()) {
         masm.storeValueFromComponents(ImmType(fe->getKnownType()), dreg.reg(), address);
     } else {
-        pinReg(dreg.reg());
         JS_ASSERT(fe->type.inMemory());
+        if (canPinDreg)
+            pinReg(dreg.reg());
+
         RegisterID treg = popped ? allocReg() : allocReg(fe, RematInfo::TYPE);
         masm.loadTypeTag(addressOf(fe), treg);
         masm.storeValueFromComponents(treg, dreg.reg(), address);
+
         if (popped)
             freeReg(treg);
         else
             fe->type.setRegister(treg);
-        unpinReg(dreg.reg());
+
+        if (canPinDreg)
+            unpinReg(dreg.reg());
     }
 
     /* If register is untracked, free it. */
     if (!wasInRegister && popped)
         freeReg(dreg.reg());
 
 #elif defined JS_NUNBOX32