Bug 1156914 - Fix the MacroAssembler::pushValue(const Address&) footgun on 32 bit platforms. (r=jandem)
☠☠ backed out by 03e1398dea10 ☠ ☠
authorEric Faust <efaustbmo@mozilla.com>
Fri, 22 May 2015 13:09:44 -0700
changeset 277598 95f9ab2b60e1cd4cbf24b31ab7d29535231f2909
parent 277597 bda0445b19507ffc6373f36b477c5502135cc2d0
child 277599 8a17732972887b2f9bf77704f96684038125738a
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1156914
milestone41.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
Bug 1156914 - Fix the MacroAssembler::pushValue(const Address&) footgun on 32 bit platforms. (r=jandem)
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/x86/MacroAssembler-x86.h
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -3557,20 +3557,19 @@ MacroAssemblerARMCompat::tagValue(JSValu
 void
 MacroAssemblerARMCompat::pushValue(ValueOperand val) {
     ma_push(val.typeReg());
     ma_push(val.payloadReg());
 }
 void
 MacroAssemblerARMCompat::pushValue(const Address& addr)
 {
-    MOZ_ASSERT(addr.base != StackPointer);
     Operand srcOp = Operand(addr);
-    Operand payload = ToPayload(srcOp);
     Operand type = ToType(srcOp);
+    Operand payload = ToPayloadAfterStackPush(srcOp);
 
     ma_ldr(type, ScratchRegister);
     ma_push(ScratchRegister);
     ma_ldr(payload, ScratchRegister);
     ma_push(ScratchRegister);
 }
 
 void
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -50,16 +50,25 @@ class MacroAssemblerARM : public Assembl
   protected:
     Operand ToType(Operand base) {
         return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void*));
     }
     Address ToType(Address base) {
         return ToType(Operand(base)).toAddress();
     }
 
+    Operand ToPayloadAfterStackPush(Operand base) {
+        Register baseReg = Register::FromCode(base.base());
+        // If we are based on StackPointer, pass over the type tag just pushed.
+        if (baseReg == StackPointer)
+            return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void*));
+        else
+            return ToPayload(base);
+    }
+
   public:
     MacroAssemblerARM()
       : secondScratchReg_(lr)
     { }
 
     void setSecondScratchReg(Register reg) {
         MOZ_ASSERT(reg != ScratchRegister);
         secondScratchReg_ = reg;
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -62,16 +62,24 @@ class MacroAssemblerX86 : public MacroAs
     Double* getDouble(double d);
     Float* getFloat(float f);
     SimdData* getSimdData(const SimdConstant& v);
 
   protected:
     MoveResolver moveResolver_;
 
   private:
+    Operand payloadOfAfterStackPush(const Address& address) {
+        // If we are basing off %esp, the address will be invalid after the
+        // first push.
+        if (address.base == StackPointer)
+            return Operand(address.base, address.offset + 4);
+        else 
+            return payloadOf(address);
+    }
     Operand payloadOf(const Address& address) {
         return Operand(address.base, address.offset);
     }
     Operand payloadOf(const BaseIndex& address) {
         return Operand(address.base, address.index, address.scale, address.offset);
     }
     Operand tagOf(const Address& address) {
         return Operand(address.base, address.offset + 4);
@@ -235,17 +243,17 @@ class MacroAssemblerX86 : public MacroAs
             push(Imm32(jv.s.payload.i32));
     }
     void pushValue(JSValueType type, Register reg) {
         push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
         push(reg);
     }
     void pushValue(const Address& addr) {
         push(tagOf(addr));
-        push(payloadOf(addr));
+        push(payloadOfAfterStackPush(addr));
     }
     void storePayload(const Value& val, Operand dest) {
         jsval_layout jv = JSVAL_TO_IMPL(val);
         if (val.isMarkable())
             movl(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), ToPayload(dest));
         else
             movl(Imm32(jv.s.payload.i32), ToPayload(dest));
     }