Bug 1178770 - Move MacroAssemblerSpecific::call to the MacroAssembler. r=h4writer
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Mon, 06 Jul 2015 16:12:48 +0200
changeset 275875 7c9a34b615aa22b31a5b4efdb81704566e951f08
parent 275874 95af75ab24cd66e1e4ae654f170f05c9197bf0de
child 275876 78ca108fd4cb3b25271e8f81a01f42e5ca9dae03
push id3246
push usergijskruitbosch@gmail.com
push dateTue, 07 Jul 2015 09:06:38 +0000
reviewersh4writer
bugs1178770
milestone42.0a1
Bug 1178770 - Move MacroAssemblerSpecific::call to the MacroAssembler. r=h4writer
js/src/jit/MacroAssembler-inl.h
js/src/jit/MacroAssembler.h
js/src/jit/arm/Assembler-arm.h
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/arm64/MacroAssembler-arm64.cpp
js/src/jit/arm64/MacroAssembler-arm64.h
js/src/jit/mips/MacroAssembler-mips.cpp
js/src/jit/mips/MacroAssembler-mips.h
js/src/jit/x64/MacroAssembler-x64.cpp
js/src/jit/x64/MacroAssembler-x64.h
js/src/jit/x64/SharedICHelpers-x64.h
js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
js/src/jit/x86-shared/MacroAssembler-x86-shared.h
js/src/jit/x86/MacroAssembler-x86.cpp
js/src/jit/x86/SharedICHelpers-x86.h
js/src/jit/x86/Trampoline-x86.cpp
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -54,17 +54,17 @@ MacroAssembler::PushWithPatch(ImmWord wo
 
 CodeOffsetLabel
 MacroAssembler::PushWithPatch(ImmPtr imm)
 {
     return PushWithPatch(ImmWord(uintptr_t(imm.value)));
 }
 
 // ===============================================================
-// Call functions.
+// Simple call functions.
 
 void
 MacroAssembler::call(const CallSiteDesc& desc, const Register reg)
 {
     call(reg);
     append(desc, currentOffset(), framePushed());
 }
 
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -345,19 +345,27 @@ class MacroAssembler : public MacroAssem
     void reserveStack(uint32_t amount) PER_ARCH;
     void freeStack(uint32_t amount);
 
     // Warning: This method does not update the framePushed() counter.
     void freeStack(Register amount);
 
   public:
     // ===============================================================
-    // Call functions.
+    // Simple call functions.
 
-    using MacroAssemblerSpecific::call; // legacy
+    void call(Register reg) PER_ARCH;
+    void call(const Address& addr) PER_ARCH ONLY_X86_X64;
+    void call(Label* label) PER_ARCH;
+    void call(ImmWord imm) PER_ARCH;
+    // Call a target native function, which is neither traceable nor movable.
+    void call(ImmPtr imm) PER_ARCH;
+    void call(AsmJSImmPtr imm) PER_ARCH;
+    // Call a target JitCode, which must be traceable, and may be movable.
+    void call(JitCode* c) PER_ARCH;
 
     inline void call(const CallSiteDesc& desc, const Register reg);
     inline void call(const CallSiteDesc& desc, Label* label);
 
   public:
 
     // Emits a test of a value against all types in a TypeSet. A scratch
     // register is required.
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1633,19 +1633,16 @@ class Assembler : public AssemblerShared
 
     void Bind(uint8_t* rawCode, AbsoluteLabel* label, const void* address);
 
     // See Bind
     size_t labelOffsetToPatchOffset(size_t offset) {
         return actualOffset(offset);
     }
 
-    void call(Label* label);
-    void call(void* target);
-
     void as_bkpt();
 
   public:
     static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
     static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader);
 
     static bool SupportsFloatingPoint() {
         return HasVFP();
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -4117,41 +4117,41 @@ MacroAssemblerARMCompat::callWithABI(voi
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust, /* callFromAsmJS = */ true);
-    call(imm);
+    asMasm().call(imm);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerARMCompat::callWithABI(const Address& fun, MoveOp::Type result)
 {
     // Load the callee in r12, no instruction between the ldr and call should
     // clobber it. Note that we can't use fun.base because it may be one of the
     // IntArg registers clobbered before the call.
     ma_ldr(fun, r12);
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(r12);
+    asMasm().call(r12);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerARMCompat::callWithABI(Register fun, MoveOp::Type result)
 {
     // Load the callee in r12, as above.
     ma_mov(fun, r12);
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(r12);
+    asMasm().call(r12);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler)
 {
     // Reserve space for exception information.
     int size = (sizeof(ResumeFromException) + 7) & ~7;
@@ -5085,16 +5085,24 @@ MacroAssemblerARMCompat::profilerEnterFr
 }
 
 void
 MacroAssemblerARMCompat::profilerExitFrame()
 {
     branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
 }
 
+void
+MacroAssemblerARMCompat::callAndPushReturnAddress(Label* label)
+{
+    AutoForbidPools afp(this, 2);
+    ma_push(pc);
+    asMasm().call(label);
+}
+
 MacroAssembler&
 MacroAssemblerARMCompat::asMasm()
 {
     return *static_cast<MacroAssembler*>(this);
 }
 
 const MacroAssembler&
 MacroAssemblerARMCompat::asMasm() const
@@ -5235,8 +5243,60 @@ MacroAssembler::Pop(const ValueOperand& 
 
 void
 MacroAssembler::reserveStack(uint32_t amount)
 {
     if (amount)
         ma_sub(Imm32(amount), sp);
     adjustFrame(amount);
 }
+
+// ===============================================================
+// Simple call functions.
+
+void
+MacroAssembler::call(Register reg)
+{
+    as_blx(reg);
+}
+
+void
+MacroAssembler::call(Label* label)
+{
+    // For now, assume that it'll be nearby?
+    as_bl(label, Always);
+}
+
+void
+MacroAssembler::call(ImmWord imm)
+{
+    call(ImmPtr((void*)imm.value));
+}
+
+void
+MacroAssembler::call(ImmPtr imm)
+{
+    BufferOffset bo = m_buffer.nextOffset();
+    addPendingJump(bo, imm, Relocation::HARDCODED);
+    ma_call(imm);
+}
+
+void
+MacroAssembler::call(AsmJSImmPtr imm)
+{
+    movePtr(imm, CallReg);
+    call(CallReg);
+}
+
+void
+MacroAssembler::call(JitCode* c)
+{
+    BufferOffset bo = m_buffer.nextOffset();
+    addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
+    RelocStyle rs;
+    if (HasMOVWT())
+        rs = L_MOVWT;
+    else
+        rs = L_LDR;
+
+    ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
+    ma_callJitHalfPush(ScratchRegister);
+}
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -533,17 +533,16 @@ class MacroAssemblerARMCompat : public M
     MoveResolver moveResolver_;
 
   public:
     MacroAssemblerARMCompat()
       : inCall_(false)
     { }
 
   public:
-    using MacroAssemblerARM::call;
 
     // Jumps + other functions that should be called from non-arm specific
     // code. Basically, an x86 front end on top of the ARM code.
     void j(Condition code , Label* dest)
     {
         as_b(dest, code);
     }
     void j(Label* dest)
@@ -562,52 +561,17 @@ class MacroAssemblerARMCompat : public M
     }
     void mov(Register src, Address dest) {
         MOZ_CRASH("NYI-IC");
     }
     void mov(Address src, Register dest) {
         MOZ_CRASH("NYI-IC");
     }
 
-    void call(const Register reg) {
-        as_blx(reg);
-    }
-    void call(Label* label) {
-        // For now, assume that it'll be nearby?
-        as_bl(label, Always);
-    }
-    void call(ImmWord imm) {
-        call(ImmPtr((void*)imm.value));
-    }
-    void call(ImmPtr imm) {
-        BufferOffset bo = m_buffer.nextOffset();
-        addPendingJump(bo, imm, Relocation::HARDCODED);
-        ma_call(imm);
-    }
-    void call(AsmJSImmPtr imm) {
-        movePtr(imm, CallReg);
-        call(CallReg);
-    }
-    void call(JitCode* c) {
-        BufferOffset bo = m_buffer.nextOffset();
-        addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
-        RelocStyle rs;
-        if (HasMOVWT())
-            rs = L_MOVWT;
-        else
-            rs = L_LDR;
-
-        ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
-        ma_callJitHalfPush(ScratchRegister);
-    }
-    void callAndPushReturnAddress(Label* label) {
-        AutoForbidPools afp(this, 2);
-        ma_push(pc);
-        call(label);
-    }
+    void callAndPushReturnAddress(Label* label);
 
     void branch(JitCode* c) {
         BufferOffset bo = m_buffer.nextOffset();
         addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
         RelocStyle rs;
         if (HasMOVWT())
             rs = L_MOVWT;
         else
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -51,21 +51,38 @@ MacroAssemblerCompat::buildFakeExitFrame
     leaveNoPool();
 
     MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
 
     *offset = pseudoReturnOffset;
 }
 
 void
+MacroAssemblerCompat::callWithExitFrame(Label* target)
+{
+    uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
+    Push(Imm32(descriptor)); // descriptor
+    asMasm().call(target);
+}
+
+void
 MacroAssemblerCompat::callWithExitFrame(JitCode* target)
 {
     uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
     asMasm().Push(Imm32(descriptor));
-    call(target);
+    asMasm().call(target);
+}
+
+void
+MacroAssemblerCompat::callWithExitFrame(JitCode* target, Register dynStack)
+{
+    add32(Imm32(framePushed()), dynStack);
+    makeFrameDescriptor(dynStack, JitFrame_IonJS);
+    Push(dynStack); // descriptor
+    asMasm().call(target);
 }
 
 void
 MacroAssembler::alignFrameForICArguments(MacroAssembler::AfterICSaveLive& aic)
 {
     // Exists for MIPS compatibility.
 }
 
@@ -436,48 +453,48 @@ MacroAssemblerCompat::callWithABI(void* 
     AssertValidABIFunctionType(passedArgTypes_);
 # endif
     ABIFunctionType type = ABIFunctionType(passedArgTypes_);
     fun = vixl::Simulator::RedirectNativeFunction(fun, type);
 #endif // JS_SIMULATOR_ARM64
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(ImmPtr(fun));
+    asMasm().call(ImmPtr(fun));
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerCompat::callWithABI(Register fun, MoveOp::Type result)
 {
     movePtr(fun, ip0);
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(ip0);
+    asMasm().call(ip0);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(imm);
+    asMasm().call(imm);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerCompat::callWithABI(Address fun, MoveOp::Type result)
 {
     loadPtr(fun, ip0);
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(ip0);
+    asMasm().call(ip0);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
                                               Label* label)
 {
     MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
@@ -679,10 +696,62 @@ MacroAssembler::Pop(const Register reg)
 
 void
 MacroAssembler::Pop(const ValueOperand& val)
 {
     pop(val);
     adjustFrame(-1 * int64_t(sizeof(int64_t)));
 }
 
+// ===============================================================
+// Simple call functions.
+
+void
+MacroAssembler::call(Register reg)
+{
+    syncStackPtr();
+    Blr(ARMRegister(reg, 64));
+}
+
+void
+MacroAssembler::call(Label* label)
+{
+    syncStackPtr();
+    Bl(label);
+}
+
+void
+MacroAssembler::call(ImmWord imm)
+{
+    call(ImmPtr((void*)imm.value));
+}
+
+void
+MacroAssembler::call(ImmPtr imm)
+{
+    syncStackPtr();
+    movePtr(imm, ip0);
+    Blr(vixl::ip0);
+}
+
+void
+MacroAssembler::call(AsmJSImmPtr imm)
+{
+    vixl::UseScratchRegisterScope temps(this);
+    const Register scratch = temps.AcquireX().asUnsized();
+    syncStackPtr();
+    movePtr(imm, scratch);
+    call(scratch);
+}
+
+void
+MacroAssembler::call(JitCode* c)
+{
+    vixl::UseScratchRegisterScope temps(this);
+    const ARMRegister scratch64 = temps.AcquireX();
+    syncStackPtr();
+    BufferOffset off = immPool64(scratch64, uint64_t(c->raw()));
+    addPendingJump(off, ImmPtr(c->raw()), Relocation::JITCODE);
+    blr(scratch64);
+}
+
 } // namespace jit
 } // namespace js
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -2701,24 +2701,16 @@ class MacroAssemblerCompat : public vixl
     void handleFailureWithHandlerTail(void* handler);
 
     // FIXME: This is the same on all platforms. Can be common code?
     void makeFrameDescriptor(Register frameSizeReg, FrameType type) {
         lshiftPtr(Imm32(FRAMESIZE_SHIFT), frameSizeReg);
         orPtr(Imm32(type), frameSizeReg);
     }
 
-    void callWithExitFrame(JitCode* target, Register dynStack) {
-        add32(Imm32(framePushed()), dynStack);
-        makeFrameDescriptor(dynStack, JitFrame_IonJS);
-        Push(dynStack); // descriptor
-
-        call(target);
-    }
-
     // FIXME: See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
     void patchAsmJSGlobalAccess(CodeOffsetLabel patchAt, uint8_t* code,
                                 uint8_t* globalData, unsigned globalDataOffset)
     {
         MOZ_CRASH("patchAsmJSGlobalAccess");
     }
 
     void memIntToValue(const Address& src, const Address& dest) {
@@ -2732,82 +2724,30 @@ class MacroAssemblerCompat : public vixl
 
     void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
     void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
 
     // Builds an exit frame on the stack, with a return address to an internal
     // non-function. Returns offset to be passed to markSafepointAt().
     void buildFakeExitFrame(Register scratch, uint32_t* offset);
 
-    void callWithExitFrame(Label* target) {
-        uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
-        Push(Imm32(descriptor)); // descriptor
-
-        call(target);
-    }
-
+    void callWithExitFrame(Label* target);
     void callWithExitFrame(JitCode* target);
+    void callWithExitFrame(JitCode* target, Register dynStack);
 
     void callJit(Register callee) {
         // AArch64 cannot read from the PC, so pushing must be handled callee-side.
         syncStackPtr();
         Blr(ARMRegister(callee, 64));
     }
 
     void appendCallSite(const CallSiteDesc& desc) {
         MOZ_CRASH("appendCallSite");
     }
 
-    void call(const CallSiteDesc& desc, Label* label) {
-        syncStackPtr();
-        call(label);
-        append(desc, currentOffset(), framePushed_);
-    }
-    void call(const CallSiteDesc& desc, Register reg) {
-        syncStackPtr();
-        call(reg);
-        append(desc, currentOffset(), framePushed_);
-    }
-    void call(const CallSiteDesc& desc, AsmJSImmPtr imm) {
-        syncStackPtr();
-        call(imm);
-        append(desc, currentOffset(), framePushed_);
-    }
-
-    void call(AsmJSImmPtr imm) {
-        vixl::UseScratchRegisterScope temps(this);
-        const Register scratch = temps.AcquireX().asUnsized();
-        syncStackPtr();
-        movePtr(imm, scratch);
-        call(scratch);
-    }
-
-    void call(Register target) {
-        syncStackPtr();
-        Blr(ARMRegister(target, 64));
-    }
-    // Call a target JitCode, which must be traceable, and may be movable.
-    void call(JitCode* target) {
-        vixl::UseScratchRegisterScope temps(this);
-        const ARMRegister scratch64 = temps.AcquireX();
-        syncStackPtr();
-        BufferOffset off = immPool64(scratch64, uint64_t(target->raw()));
-        addPendingJump(off, ImmPtr(target->raw()), Relocation::JITCODE);
-        blr(scratch64);
-    }
-    // Call a target native function, which is neither traceable nor movable.
-    void call(ImmPtr target) {
-        syncStackPtr();
-        movePtr(target, ip0);
-        Blr(vixl::ip0);
-    }
-    void call(Label* target) {
-        syncStackPtr();
-        Bl(target);
-    }
     void callExit(AsmJSImmPtr imm, uint32_t stackArgBytes) {
         MOZ_CRASH("callExit");
     }
 
     void callJitFromAsmJS(Register reg) {
         Blr(ARMRegister(reg, 64));
     }
 
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -3440,42 +3440,42 @@ MacroAssemblerMIPSCompat::callWithABI(vo
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerMIPSCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust, /* callFromAsmJS = */ true);
-    call(imm);
+    asMasm().call(imm);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerMIPSCompat::callWithABI(const Address& fun, MoveOp::Type result)
 {
     // Load the callee in t9, no instruction between the lw and call
     // should clobber it. Note that we can't use fun.base because it may
     // be one of the IntArg registers clobbered before the call.
     ma_lw(t9, Address(fun.base, fun.offset));
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(t9);
+    asMasm().call(t9);
     callWithABIPost(stackAdjust, result);
 
 }
 
 void
 MacroAssemblerMIPSCompat::callWithABI(Register fun, MoveOp::Type result)
 {
     // Load the callee in t9, as above.
     ma_move(t9, fun);
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(t9);
+    asMasm().call(t9);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerMIPSCompat::handleFailureWithHandlerTail(void* handler)
 {
     // Reserve space for exception information.
     int size = (sizeof(ResumeFromException) + ABIStackAlignment) & ~(ABIStackAlignment - 1);
@@ -3771,8 +3771,54 @@ MacroAssembler::Pop(const ValueOperand& 
 
 void
 MacroAssembler::reserveStack(uint32_t amount)
 {
     if (amount)
         ma_subu(StackPointer, StackPointer, Imm32(amount));
     adjustFrame(amount);
 }
+
+// ===============================================================
+// Simple call functions.
+
+void
+MacroAssembler::call(Register reg)
+{
+    as_jalr(reg);
+    as_nop();
+}
+
+void
+MacroAssembler::call(Label* label)
+{
+    ma_bal(label);
+}
+
+void
+MacroAssembler::call(AsmJSImmPtr target)
+{
+    movePtr(target, CallReg);
+    call(CallReg);
+}
+
+void
+MacroAssembler::call(ImmWord target)
+{
+    call(ImmPtr((void*)target.value));
+}
+
+void
+MacroAssembler::call(ImmPtr target)
+{
+    BufferOffset bo = m_buffer.nextOffset();
+    addPendingJump(bo, target, Relocation::HARDCODED);
+    ma_call(target);
+}
+
+void
+MacroAssembler::call(JitCode* c)
+{
+    BufferOffset bo = m_buffer.nextOffset();
+    addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
+    ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
+    ma_callJitHalfPush(ScratchRegister);
+}
--- a/js/src/jit/mips/MacroAssembler-mips.h
+++ b/js/src/jit/mips/MacroAssembler-mips.h
@@ -400,44 +400,16 @@ class MacroAssemblerMIPSCompat : public 
     }
     void mov(Register src, Address dest) {
         MOZ_CRASH("NYI-IC");
     }
     void mov(Address src, Register dest) {
         MOZ_CRASH("NYI-IC");
     }
 
-    void call(const Register reg) {
-        as_jalr(reg);
-        as_nop();
-    }
-
-    void call(Label* label) {
-        ma_bal(label);
-    }
-
-    void call(ImmWord imm) {
-        call(ImmPtr((void*)imm.value));
-    }
-    void call(ImmPtr imm) {
-        BufferOffset bo = m_buffer.nextOffset();
-        addPendingJump(bo, imm, Relocation::HARDCODED);
-        ma_call(imm);
-    }
-    void call(AsmJSImmPtr imm) {
-        movePtr(imm, CallReg);
-        call(CallReg);
-    }
-    void call(JitCode* c) {
-        BufferOffset bo = m_buffer.nextOffset();
-        addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
-        ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
-        ma_callJitHalfPush(ScratchRegister);
-    }
-
     void callAndPushReturnAddress(Label* label) {
         ma_callJitHalfPush(label);
     }
 
     void branch(JitCode* c) {
         BufferOffset bo = m_buffer.nextOffset();
         addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
         ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -318,26 +318,26 @@ MacroAssemblerX64::callWithABIPost(uint3
     inCall_ = false;
 }
 
 void
 MacroAssemblerX64::callWithABI(void* fun, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(ImmPtr(fun));
+    asMasm().call(ImmPtr(fun));
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(imm);
+    asMasm().call(imm);
     callWithABIPost(stackAdjust, result);
 }
 
 static bool
 IsIntArgReg(Register reg)
 {
     for (uint32_t i = 0; i < NumIntArgRegs; i++) {
         if (IntArgRegs[i] == reg)
@@ -356,17 +356,17 @@ MacroAssemblerX64::callWithABI(Address f
         moveResolver_.addMove(MoveOperand(fun.base), MoveOperand(r10), MoveOp::GENERAL);
         fun.base = r10;
     }
 
     MOZ_ASSERT(!IsIntArgReg(fun.base));
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(Operand(fun));
+    asMasm().call(fun);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX64::callWithABI(Register fun, MoveOp::Type result)
 {
     if (IsIntArgReg(fun)) {
         // Callee register may be clobbered for an argument. Move the callee to
@@ -374,17 +374,17 @@ MacroAssemblerX64::callWithABI(Register 
         moveResolver_.addMove(MoveOperand(fun), MoveOperand(r10), MoveOp::GENERAL);
         fun = r10;
     }
 
     MOZ_ASSERT(!IsIntArgReg(fun));
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(Operand(fun));
+    asMasm().call(fun);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX64::handleFailureWithHandlerTail(void* handler)
 {
     // Reserve space for exception information.
     subq(Imm32(sizeof(ResumeFromException)), rsp);
@@ -508,17 +508,17 @@ MacroAssemblerX64::storeUnboxedValue(Con
                                      MIRType slotType);
 
 void
 MacroAssemblerX64::callWithExitFrame(JitCode* target, Register dynStack)
 {
     addPtr(Imm32(asMasm().framePushed()), dynStack);
     makeFrameDescriptor(dynStack, JitFrame_IonJS);
     asMasm().Push(dynStack);
-    call(target);
+    asMasm().call(target);
 }
 
 void
 MacroAssemblerX64::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
 {
     MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
     MOZ_ASSERT(ptr != temp);
     MOZ_ASSERT(ptr != ScratchReg);
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -84,17 +84,16 @@ class MacroAssemblerX64 : public MacroAs
     SimdMap simdMap_;
 
     void setupABICall(uint32_t arg);
 
   protected:
     MoveResolver moveResolver_;
 
   public:
-    using MacroAssemblerX86Shared::call;
     using MacroAssemblerX86Shared::callWithExitFrame;
     using MacroAssemblerX86Shared::branch32;
     using MacroAssemblerX86Shared::branchTest32;
     using MacroAssemblerX86Shared::load32;
     using MacroAssemblerX86Shared::store32;
 
     MacroAssemblerX64()
       : inCall_(false)
@@ -103,23 +102,16 @@ class MacroAssemblerX64 : public MacroAs
 
     // The buffer is about to be linked, make sure any constant pools or excess
     // bookkeeping has been flushed to the instruction stream.
     void finish();
 
     /////////////////////////////////////////////////////////////////
     // X64 helpers.
     /////////////////////////////////////////////////////////////////
-    void call(ImmWord target) {
-        mov(target, rax);
-        call(rax);
-    }
-    void call(ImmPtr target) {
-        call(ImmWord(uintptr_t(target.value)));
-    }
     void writeDataRelocation(const Value& val) {
         if (val.isMarkable()) {
             gc::Cell* cell = reinterpret_cast<gc::Cell*>(val.toGCThing());
             if (cell && gc::IsInsideNursery(cell))
                 embedsNurseryPointers_ = true;
             dataRelocations_.writeUnsigned(masm.currentOffset());
         }
     }
--- a/js/src/jit/x64/SharedICHelpers-x64.h
+++ b/js/src/jit/x64/SharedICHelpers-x64.h
@@ -37,17 +37,17 @@ EmitCallIC(CodeOffsetLabel* patchOffset,
     CodeOffsetLabel offset = masm.movWithPatch(ImmWord(-1), ICStubReg);
     *patchOffset = offset;
 
     // Load stub pointer into ICStubReg
     masm.loadPtr(Address(ICStubReg, (int32_t) ICEntry::offsetOfFirstStub()),
                  ICStubReg);
 
     // Call the stubcode.
-    masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
+    masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
 }
 
 inline void
 EmitEnterTypeMonitorIC(MacroAssembler& masm,
                        size_t monitorStubOffset = ICMonitoredStub::offsetOfFirstMonitorStub())
 {
     // This is expected to be called from within an IC, when ICStubReg
     // is properly initialized to point to the stub.
@@ -225,17 +225,17 @@ EmitCallTypeUpdateIC(MacroAssembler& mas
     masm.push(ICStubReg);
 
     // This is expected to be called from within an IC, when ICStubReg
     // is properly initialized to point to the stub.
     masm.loadPtr(Address(ICStubReg, (int32_t) ICUpdatedStub::offsetOfFirstUpdateStub()),
                  ICStubReg);
 
     // Call the stubcode.
-    masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
+    masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
 
     // Restore the old stub reg.
     masm.pop(ICStubReg);
 
     // The update IC will store 0 or 1 in R1.scratchReg() reflecting if the
     // value in R0 type-checked properly or not.
     Label success;
     masm.cmp32(R1.scratchReg(), Imm32(1));
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
@@ -160,16 +160,34 @@ MacroAssemblerX86Shared::branchNegativeZ
                                                    Register scratch,
                                                    Label* label)
 {
     vmovd(reg, scratch);
     cmp32(scratch, Imm32(1));
     j(Overflow, label);
 }
 
+void
+MacroAssemblerX86Shared::callJit(Register callee)
+{
+    call(callee);
+}
+
+void
+MacroAssemblerX86Shared::callJitFromAsmJS(Register callee)
+{
+    call(callee);
+}
+
+void
+MacroAssemblerX86Shared::callAndPushReturnAddress(Label* label)
+{
+    call(label);
+}
+
 MacroAssembler&
 MacroAssemblerX86Shared::asMasm()
 {
     return *static_cast<MacroAssembler*>(this);
 }
 
 const MacroAssembler&
 MacroAssemblerX86Shared::asMasm() const
@@ -345,8 +363,55 @@ MacroAssembler::Pop(FloatRegister reg)
 }
 
 void
 MacroAssembler::Pop(const ValueOperand& val)
 {
     popValue(val);
     framePushed_ -= sizeof(Value);
 }
+
+// ===============================================================
+// Simple call functions.
+
+void
+MacroAssembler::call(Register reg)
+{
+    Assembler::call(reg);
+}
+
+void
+MacroAssembler::call(Label* label)
+{
+    Assembler::call(label);
+}
+
+void
+MacroAssembler::call(const Address& addr)
+{
+    Assembler::call(Operand(addr.base, addr.offset));
+}
+
+void
+MacroAssembler::call(AsmJSImmPtr target)
+{
+    mov(target, eax);
+    Assembler::call(eax);
+}
+
+void
+MacroAssembler::call(ImmWord target)
+{
+    mov(target, eax);
+    Assembler::call(eax);
+}
+
+void
+MacroAssembler::call(ImmPtr target)
+{
+    call(ImmWord(uintptr_t(target.value)));
+}
+
+void
+MacroAssembler::call(JitCode* target)
+{
+    Assembler::call(target);
+}
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
@@ -1428,29 +1428,19 @@ class MacroAssemblerX86Shared : public A
     }
 
     // Builds an exit frame on the stack, with a return address to an internal
     // non-function. Returns offset to be passed to markSafepointAt().
     void buildFakeExitFrame(Register scratch, uint32_t* offset);
     void callWithExitFrame(Label* target);
     void callWithExitFrame(JitCode* target);
 
-    void callJit(Register callee) {
-        call(callee);
-    }
-    void callJitFromAsmJS(Register callee) {
-        call(callee);
-    }
-    void call(AsmJSImmPtr target) {
-        mov(target, eax);
-        call(eax);
-    }
-    void callAndPushReturnAddress(Label* label) {
-        call(label);
-    }
+    void callJit(Register callee);
+    void callJitFromAsmJS(Register callee);
+    void callAndPushReturnAddress(Label* label);
 
     void checkStackAlignment() {
         // Exists for ARM compatibility.
     }
 
     CodeOffsetLabel labelForPatch() {
         return CodeOffsetLabel(size());
     }
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -323,44 +323,44 @@ MacroAssemblerX86::callWithABIPost(uint3
     inCall_ = false;
 }
 
 void
 MacroAssemblerX86::callWithABI(void* fun, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(ImmPtr(fun));
+    asMasm().call(ImmPtr(fun));
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(fun);
+    asMasm().call(fun);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX86::callWithABI(const Address& fun, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(Operand(fun));
+    asMasm().call(fun);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX86::callWithABI(Register fun, MoveOp::Type result)
 {
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
-    call(Operand(fun));
+    asMasm().call(fun);
     callWithABIPost(stackAdjust, result);
 }
 
 void
 MacroAssemblerX86::handleFailureWithHandlerTail(void* handler)
 {
     // Reserve space for exception information.
     subl(Imm32(sizeof(ResumeFromException)), esp);
@@ -501,17 +501,17 @@ MacroAssemblerX86::storeUnboxedValue(Con
                                      MIRType slotType);
 
 void
 MacroAssemblerX86::callWithExitFrame(JitCode* target, Register dynStack)
 {
     addPtr(ImmWord(asMasm().framePushed()), dynStack);
     makeFrameDescriptor(dynStack, JitFrame_IonJS);
     asMasm().Push(dynStack);
-    call(target);
+    asMasm().call(target);
 }
 
 void
 MacroAssemblerX86::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
                                            Label* label)
 {
     MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
     MOZ_ASSERT(ptr != temp);
--- a/js/src/jit/x86/SharedICHelpers-x86.h
+++ b/js/src/jit/x86/SharedICHelpers-x86.h
@@ -38,17 +38,17 @@ EmitCallIC(CodeOffsetLabel* patchOffset,
     *patchOffset = offset;
 
     // Load stub pointer into ICStubReg
     masm.loadPtr(Address(ICStubReg, (int32_t) ICEntry::offsetOfFirstStub()),
                  ICStubReg);
 
     // Load stubcode pointer from BaselineStubEntry into ICTailCallReg
     // ICTailCallReg will always be unused in the contexts where ICs are called.
-    masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
+    masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
 }
 
 inline void
 EmitEnterTypeMonitorIC(MacroAssembler& masm,
                        size_t monitorStubOffset = ICMonitoredStub::offsetOfFirstMonitorStub())
 {
     // This is expected to be called from within an IC, when ICStubReg
     // is properly initialized to point to the stub.
@@ -231,17 +231,17 @@ EmitCallTypeUpdateIC(MacroAssembler& mas
     masm.push(ICStubReg);
 
     // This is expected to be called from within an IC, when ICStubReg
     // is properly initialized to point to the stub.
     masm.loadPtr(Address(ICStubReg, (int32_t) ICUpdatedStub::offsetOfFirstUpdateStub()),
                  ICStubReg);
 
     // Call the stubcode.
-    masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
+    masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
 
     // Restore the old stub reg.
     masm.pop(ICStubReg);
 
     // The update IC will store 0 or 1 in R1.scratchReg() reflecting if the
     // value in R0 type-checked properly or not.
     Label success;
     masm.cmp32(R1.scratchReg(), Imm32(1));
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -269,17 +269,17 @@ JitRuntime::generateEnterJIT(JSContext* 
     // The call will push the return address on the stack, thus we check that
     // the stack would be aligned once the call is complete.
     masm.assertStackAlignment(JitStackAlignment, sizeof(uintptr_t));
 
     /***************************************************************
         Call passed-in code, get return value and fill in the
         passed in return value pointer
     ***************************************************************/
-    masm.call(Operand(ebp, ARG_JITCODE));
+    masm.call(Address(ebp, ARG_JITCODE));
 
     if (type == EnterJitBaseline) {
         // Baseline OSR will return here.
         masm.bind(returnLabel.src());
         masm.addCodeLabel(returnLabel);
     }
 
     // Pop arguments off the stack.