Bug 1184965 part 1 - Factor MacroAssembler::callJit. r=bbouvier
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Tue, 01 Sep 2015 11:58:44 +0200
changeset 260298 0de036b80c64c8778d61263d1aed31217a494d9f
parent 260297 8f3f0973102210afa88ca9f98fa41f5ef26cd82f
child 260299 c35d8212f83591dd9bd37e120e3f6796485bdf9b
push id29307
push userryanvm@gmail.com
push dateWed, 02 Sep 2015 01:01:53 +0000
treeherdermozilla-central@e2eb0442ece9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1184965
milestone43.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 1184965 part 1 - Factor MacroAssembler::callJit. r=bbouvier
js/src/asmjs/AsmJSValidate.cpp
js/src/jit/MacroAssembler-inl.h
js/src/jit/MacroAssembler.h
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/arm/Trampoline-arm.cpp
js/src/jit/arm64/MacroAssembler-arm64.cpp
js/src/jit/arm64/MacroAssembler-arm64.h
js/src/jit/arm64/Trampoline-arm64.cpp
js/src/jit/mips32/MacroAssembler-mips32.cpp
js/src/jit/mips32/MacroAssembler-mips32.h
js/src/jit/mips32/Trampoline-mips32.cpp
js/src/jit/none/MacroAssembler-none.h
js/src/jit/x64/Trampoline-x64.cpp
js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
js/src/jit/x86-shared/MacroAssembler-x86-shared.h
js/src/jit/x86/Trampoline-x86.cpp
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -11448,17 +11448,17 @@ GenerateFFIIonExit(ModuleCompiler& m, co
         //   act.prevProfilingActivation_ = cx->runtime()->profilingActivation;
         masm.loadPtr(Address(reg0, offsetOfProfilingActivation), reg2);
         masm.storePtr(reg2, Address(reg1, Activation::offsetOfPrevProfiling()));
         //   cx->runtime()->profilingActivation_ = act;
         masm.storePtr(reg1, Address(reg0, offsetOfProfilingActivation));
     }
 
     AssertStackAlignment(masm, JitStackAlignment, sizeOfRetAddr);
-    masm.callJitFromAsmJS(callee);
+    masm.callJitNoProfiler(callee);
     AssertStackAlignment(masm, JitStackAlignment, sizeOfRetAddr);
 
     {
         // Disable Activation.
         //
         // This sequence needs three registers, and must preserve the JSReturnReg_Data and
         // JSReturnReg_Type, so there are five live registers.
         MOZ_ASSERT(JSReturnReg_Data == AsmJSIonExitRegReturnData);
--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -147,16 +147,28 @@ MacroAssembler::signature() const
 
     return ABIFunctionType(signature_);
 #else
     // No simulator enabled.
     MOZ_CRASH("Only available for making calls within a simulator.");
 #endif
 }
 
+// ===============================================================
+// Jit Frames.
+
+uint32_t
+MacroAssembler::callJit(Register callee)
+{
+    profilerPreCall();
+    uint32_t ret = callJitNoProfiler(callee);
+    profilerPostReturn();
+    return ret;
+}
+
 //}}} check_macroassembler_style
 // ===============================================================
 
 void
 MacroAssembler::PushStubCode()
 {
     exitCodePatch_ = PushWithPatch(ImmWord(-1));
 }
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -558,16 +558,34 @@ class MacroAssembler : public MacroAssem
 
 #ifdef JS_SIMULATOR
     // The signature is used to accumulate all types of arguments which are used
     // by the caller. This is used by the simulators to decode the arguments
     // properly, and cast the function pointer to the right type.
     uint32_t signature_;
 #endif
 
+  public:
+    // ===============================================================
+    // Jit Frames.
+    //
+    // These functions are used to build the content of the Jit frames.  See
+    // CommonFrameLayout class, and all its derivatives. The content should be
+    // pushed in the opposite order as the fields of the structures, such that
+    // the structures can be used to interpret the content of the stack.
+
+    // Call the Jit function, and push the return address (or let the callee
+    // push the return address).
+    //
+    // These functions return the offset of the return address, in order to use
+    // the return address to index the safepoints, which are used to list all
+    // live registers.
+    uint32_t callJitNoProfiler(Register callee) PER_SHARED_ARCH;
+    inline uint32_t callJit(Register callee);
+
     //}}} check_macroassembler_style
   public:
 
     // Emits a test of a value against all types in a TypeSet. A scratch
     // register is required.
     template <typename Source>
     void guardTypeSet(const Source& address, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss);
 
@@ -1088,25 +1106,16 @@ class MacroAssembler : public MacroAssem
     // These functions exist as small wrappers around sites where execution can
     // leave the currently running stream of instructions. They exist so that
     // instrumentation may be put in place around them if necessary and the
     // instrumentation is enabled. For the functions that return a uint32_t,
     // they are returning the offset of the assembler just after the call has
     // been made so that a safepoint can be made at that location.
 
     // see above comment for what is returned
-    uint32_t callJit(Register callee) {
-        profilerPreCall();
-        MacroAssemblerSpecific::callJit(callee);
-        uint32_t ret = currentOffset();
-        profilerPostReturn();
-        return ret;
-    }
-
-    // see above comment for what is returned
     uint32_t callWithExitFrame(Label* target) {
         profilerPreCall();
         MacroAssemblerSpecific::callWithExitFrame(target);
         uint32_t ret = currentOffset();
         profilerPostReturn();
         return ret;
     }
 
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -1944,23 +1944,16 @@ MacroAssemblerARMCompat::callWithExitFra
         rs = L_LDR;
 
     ScratchRegisterScope scratch(asMasm());
     ma_movPatchable(ImmPtr(target->raw()), scratch, Always, rs);
     ma_callJitHalfPush(scratch);
 }
 
 void
-MacroAssemblerARMCompat::callJit(Register callee)
-{
-    MOZ_ASSERT((asMasm().framePushed() & 7) == 4);
-    ma_callJitHalfPush(callee);
-}
-
-void
 MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic)
 {
     // Exists for MIPS compatibility.
 }
 
 void
 MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic)
 {
@@ -5302,9 +5295,21 @@ MacroAssembler::callWithABINoProfiler(co
     // IntArg registers clobbered before the call.
     ma_ldr(fun, r12);
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(r12);
     callWithABIPost(stackAdjust, result);
 }
 
+// ===============================================================
+// Jit Frames.
+
+uint32_t
+MacroAssembler::callJitNoProfiler(Register callee)
+{
+    // The return address is pushed by callee, which pushes the link register
+    // first.
+    call(callee);
+    return currentOffset();
+}
+
 //}}} check_macroassembler_style
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -1202,21 +1202,16 @@ class MacroAssemblerARMCompat : public M
     // 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 callWithExitFrame(JitCode* target, Register dynStack);
 
-    // Makes a call using the only two methods that it is sane for
-    // independent code to make a call.
-    void callJit(Register callee);
-    void callJitFromAsmJS(Register callee) { as_blx(callee); }
-
     void add32(Register src, Register dest);
     void add32(Imm32 imm, Register dest);
     void add32(Imm32 imm, const Address& dest);
     void sub32(Imm32 imm, Register dest);
     void sub32(Register src, Register dest);
     template <typename T>
     void branchAdd32(Condition cond, T src, Register dest, Label* label) {
         add32(src, dest);
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -343,17 +343,17 @@ JitRuntime::generateEnterJIT(JSContext* 
     // transfer did before making the call.
     masm.addPtr(Imm32(sizeof(uintptr_t)), sp);
 
     // The callee 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 the function.
-    masm.ma_callJitHalfPush(r0);
+    masm.callJitNoProfiler(r0);
 
     if (type == EnterJitBaseline) {
         // Baseline OSR will return here.
         masm.bind(&returnLabel);
     }
 
     // The top of the stack now points to the address of the field following the
     // return address because the return address is popped for the return, so we
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -620,12 +620,24 @@ MacroAssembler::callWithABINoProfiler(co
     loadPtr(fun, scratch);
 
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(scratch);
     callWithABIPost(stackAdjust, result);
 }
 
+// ===============================================================
+// Jit Frames.
+
+uint32_t
+MacroAssembler::callJitNoProfiler(Register callee)
+{
+    // The return address is pushed by callee, which pushes the link register
+    // first.
+    call(callee);
+    return currentOffset();
+}
+
 //}}} check_macroassembler_style
 
 } // namespace jit
 } // namespace js
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -2668,34 +2668,24 @@ class MacroAssemblerCompat : public vixl
     // 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 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 callExit(AsmJSImmPtr imm, uint32_t stackArgBytes) {
         MOZ_CRASH("callExit");
     }
 
-    void callJitFromAsmJS(Register reg) {
-        Blr(ARMRegister(reg, 64));
-    }
-
     void callAndPushReturnAddress(Label* label);
 
     void profilerEnterFrame(Register framePtr, Register scratch) {
         AbsoluteAddress activation(GetJitContext()->runtime->addressOfProfilingActivation());
         loadPtr(activation, scratch);
         storePtr(framePtr, Address(scratch, JitActivation::offsetOfLastProfilingFrame()));
         storePtr(ImmPtr(nullptr), Address(scratch, JitActivation::offsetOfLastProfilingCallSite()));
     }
--- a/js/src/jit/arm64/Trampoline-arm64.cpp
+++ b/js/src/jit/arm64/Trampoline-arm64.cpp
@@ -220,17 +220,17 @@ JitRuntime::generateEnterJIT(JSContext* 
         masm.B(&osrReturnPoint);
 
         masm.bind(&notOsr);
         masm.movePtr(reg_scope, R1_);
     }
 
     // Call function.
     // Since AArch64 doesn't have the pc register available, the callee must push lr.
-    masm.call(reg_code);
+    masm.callJitNoProfiler(reg_code);
 
     // Baseline OSR will return here.
     if (type == EnterJitBaseline)
         masm.bind(&osrReturnPoint);
 
     // Return back to SP.
     masm.Pop(r19);
     masm.Add(masm.GetStackPointer64(), masm.GetStackPointer64(),
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -1556,23 +1556,16 @@ MacroAssemblerMIPSCompat::callWithExitFr
     asMasm().Push(dynStack); // descriptor
 
     addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
     ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
     ma_callJitHalfPush(ScratchRegister);
 }
 
 void
-MacroAssemblerMIPSCompat::callJit(Register callee)
-{
-    MOZ_ASSERT((asMasm().framePushed() & 7) == 4);
-    ma_callJitHalfPush(callee);
-}
-
-void
 MacroAssemblerMIPSCompat::add32(Register src, Register dest)
 {
     as_addu(dest, dest, src);
 }
 
 void
 MacroAssemblerMIPSCompat::add32(Imm32 imm, Register dest)
 {
@@ -3617,9 +3610,22 @@ MacroAssembler::callWithABINoProfiler(co
     // Load the callee in t9, as above.
     ma_lw(t9, Address(fun.base, fun.offset));
     uint32_t stackAdjust;
     callWithABIPre(&stackAdjust);
     call(t9);
     callWithABIPost(stackAdjust, result);
 }
 
+// ===============================================================
+// Jit Frames.
+
+uint32_t
+MacroAssembler::callJitNoProfiler(Register callee)
+{
+    // This is a MIPS hack to push return address during jalr delay slot.
+    as_addiu(StackPointer, StackPointer, -sizeof(intptr_t));
+    as_jalr(callee);
+    as_sw(ra, StackPointer, 0);
+    return currentOffset();
+}
+
 //}}} check_macroassembler_style
--- a/js/src/jit/mips32/MacroAssembler-mips32.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32.h
@@ -1120,21 +1120,16 @@ public:
     // 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 callWithExitFrame(JitCode* target, Register dynStack);
 
-    // Makes a call using the only two methods that it is sane for indep code
-    // to make a call.
-    void callJit(Register callee);
-    void callJitFromAsmJS(Register callee) { callJit(callee); }
-
     void add32(Register src, Register dest);
     void add32(Imm32 imm, Register dest);
     void add32(Imm32 imm, const Address& dest);
     void sub32(Imm32 imm, Register dest);
     void sub32(Register src, Register dest);
 
     void incrementInt32Value(const Address& addr) {
         add32(Imm32(1), ToPayload(addr));
--- a/js/src/jit/mips32/Trampoline-mips32.cpp
+++ b/js/src/jit/mips32/Trampoline-mips32.cpp
@@ -298,17 +298,17 @@ JitRuntime::generateEnterJIT(JSContext* 
         masm.loadPtr(slotScopeChain, R1.scratchReg());
     }
 
     // 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 the function with pushing return address to stack.
-    masm.ma_callJitHalfPush(reg_code);
+    masm.callJitNoProfiler(reg_code);
 
     if (type == EnterJitBaseline) {
         // Baseline OSR will return here.
         masm.bind(returnLabel.src());
         masm.addCodeLabel(returnLabel);
     }
 
     // Pop arguments off the stack.
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -196,19 +196,16 @@ class MacroAssemblerNone : public Assemb
     template <typename T> void call(T) { MOZ_CRASH(); }
     template <typename T, typename S> void call(T, S) { MOZ_CRASH(); }
     void callAndPushReturnAddress(Label* label) { MOZ_CRASH(); }
 
     void callWithExitFrame(Label*) { MOZ_CRASH(); }
     void callWithExitFrame(JitCode*) { MOZ_CRASH(); }
     void callWithExitFrame(JitCode*, Register) { MOZ_CRASH(); }
 
-    void callJit(Register callee) { MOZ_CRASH(); }
-    void callJitFromAsmJS(Register callee) { MOZ_CRASH(); }
-
     void nop() { MOZ_CRASH(); }
     void breakpoint() { MOZ_CRASH(); }
     void abiret() { MOZ_CRASH(); }
     void ret() { MOZ_CRASH(); }
 
     CodeOffsetLabel toggledJump(Label*) { MOZ_CRASH(); }
     CodeOffsetLabel toggledCall(JitCode*, bool) { MOZ_CRASH(); }
     static size_t ToggledCallSize(uint8_t*) { MOZ_CRASH(); }
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -277,17 +277,17 @@ JitRuntime::generateEnterJIT(JSContext* 
         masm.movq(scopeChain, R1.scratchReg());
     }
 
     // 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 function.
-    masm.call(reg_code);
+    masm.callJitNoProfiler(reg_code);
 
     if (type == EnterJitBaseline) {
         // Baseline OSR will return here.
         masm.bind(returnLabel.src());
         masm.addCodeLabel(returnLabel);
     }
 
     // Pop arguments and padding from stack.
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
@@ -164,28 +164,16 @@ MacroAssemblerX86Shared::branchNegativeZ
                                                    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()
 {
@@ -415,9 +403,19 @@ MacroAssembler::call(ImmPtr target)
 }
 
 void
 MacroAssembler::call(JitCode* target)
 {
     Assembler::call(target);
 }
 
+// ===============================================================
+// Jit Frames.
+
+uint32_t
+MacroAssembler::callJitNoProfiler(Register callee)
+{
+    call(callee);
+    return currentOffset();
+}
+
 //}}} check_macroassembler_style
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
@@ -1474,18 +1474,16 @@ 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);
-    void callJitFromAsmJS(Register callee);
     void callAndPushReturnAddress(Label* label);
 
     void checkStackAlignment() {
         // Exists for ARM compatibility.
     }
 
     CodeOffsetLabel labelForPatch() {
         return CodeOffsetLabel(size());
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -512,18 +512,17 @@ JitRuntime::generateArgumentsRectifier(J
     masm.push(eax); // callee token
     masm.push(ebx); // descriptor
 
     // Call the target function.
     // Note that this assumes the function is JITted.
     masm.andl(Imm32(CalleeTokenMask), eax);
     masm.loadPtr(Address(eax, JSFunction::offsetOfNativeOrScript()), eax);
     masm.loadBaselineOrIonRaw(eax, eax, nullptr);
-    masm.call(eax);
-    uint32_t returnOffset = masm.currentOffset();
+    uint32_t returnOffset = masm.callJitNoProfiler(eax);
 
     // Remove the rectifier frame.
     masm.pop(ebx);            // ebx <- descriptor with FrameType.
     masm.shrl(Imm32(FRAMESIZE_SHIFT), ebx); // ebx <- descriptor.
     masm.pop(edi);            // Discard calleeToken.
     masm.pop(edi);            // Discard number of actual arguments.
 
     // Discard pushed arguments, but not the pushed frame pointer.