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 283143 7c9a34b615aa22b31a5b4efdb81704566e951f08
parent 283142 95af75ab24cd66e1e4ae654f170f05c9197bf0de
child 283144 78ca108fd4cb3b25271e8f81a01f42e5ca9dae03
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1178770
milestone42.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 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.