Bug 1249493 - IonMonkey: MIPS: Fix crash after enable shared stubs. r=h4writer
authorHeiher <r@hev.cc>
Fri, 19 Feb 2016 17:09:08 +0800
changeset 307816 48d6e2969e6a393722c4c7b953f8c35d25d85d69
parent 307815 1a35a3779c7f6722e6547b02d00f232506b7fc9d
child 307817 23b8141fddd46dd6d958e71c8431712294da323d
push id9214
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:25:21 +0000
treeherdermozilla-aurora@8849dd1a4a79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1249493
milestone47.0a1
Bug 1249493 - IonMonkey: MIPS: Fix crash after enable shared stubs. r=h4writer --- .../jit/mips-shared/SharedICHelpers-mips-shared.h | 38 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-)
js/src/jit/mips-shared/SharedICHelpers-mips-shared.h
--- a/js/src/jit/mips-shared/SharedICHelpers-mips-shared.h
+++ b/js/src/jit/mips-shared/SharedICHelpers-mips-shared.h
@@ -103,17 +103,28 @@ EmitBaselineTailCallVM(JitCode* target, 
     masm.storePtr(ra, Address(StackPointer, CommonFrameLayout::offsetOfReturnAddress()));
 
     masm.branch(target);
 }
 
 inline void
 EmitIonTailCallVM(JitCode* target, MacroAssembler& masm, uint32_t stackSize)
 {
-    MOZ_CRASH("Not implemented yet.");
+    Register scratch = R2.scratchReg();
+
+    masm.loadPtr(Address(sp, stackSize), scratch);
+    masm.rshiftPtr(Imm32(FRAMESIZE_SHIFT), scratch);
+    masm.addPtr(Imm32(stackSize + JitStubFrameLayout::Size() - sizeof(intptr_t)), scratch);
+
+    // Push frame descriptor and perform the tail call.
+    MOZ_ASSERT(ICTailCallReg == ra);
+    masm.makeFrameDescriptor(scratch, JitFrame_IonJS, ExitFrameLayout::Size());
+    masm.push(scratch);
+    masm.push(ICTailCallReg);
+    masm.branch(target);
 }
 
 inline void
 EmitBaselineCreateStubFrameDescriptor(MacroAssembler& masm, Register reg, uint32_t headerSize)
 {
     // Compute stub frame size. We have to add two pointers: the stub reg and
     // previous frame pointer pushed by EmitEnterStubFrame.
     masm.movePtr(BaselineFrameReg, reg);
@@ -130,17 +141,27 @@ EmitBaselineCallVM(JitCode* target, Macr
     EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
     masm.push(scratch);
     masm.call(target);
 }
 
 inline void
 EmitIonCallVM(JitCode* target, size_t stackSlots, MacroAssembler& masm)
 {
-    MOZ_CRASH("Not implemented yet.");
+    uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_IonStub,
+                                              ExitFrameLayout::Size());
+    masm.Push(Imm32(descriptor));
+    masm.callJit(target);
+
+    // Remove rest of the frame left on the stack. We remove the return address
+    // which is implicitly popped when returning.
+    size_t framePop = sizeof(ExitFrameLayout) - sizeof(void*);
+
+    // Pop arguments from framePushed.
+    masm.implicitPop(stackSlots * sizeof(void*) + framePop);
 }
 
 struct BaselineStubFrame {
     uintptr_t savedFrame;
     uintptr_t savedStub;
     uintptr_t returnAddress;
     uintptr_t descriptor;
 };
@@ -179,17 +200,25 @@ EmitBaselineEnterStubFrame(MacroAssemble
 
     // Stack should remain aligned.
     masm.checkStackAlignment();
 }
 
 inline void
 EmitIonEnterStubFrame(MacroAssembler& masm, Register scratch)
 {
-    MOZ_CRASH("Not implemented yet.");
+    MOZ_ASSERT(ICTailCallReg == ra);
+
+    // In MIPS the ra register contains the return address,
+    // but in jit frames we expect it to be on the stack. As a result
+    // push the link register (which is actually part of the previous frame.
+    // Therefore using push instead of Push).
+    masm.push(ICTailCallReg);
+
+    masm.Push(ICStubReg);
 }
 
 inline void
 EmitBaselineLeaveStubFrame(MacroAssembler& masm, bool calledIntoIon = false)
 {
     // Ion frames do not save and restore the frame pointer. If we called
     // into Ion, we have to restore the stack pointer from the frame descriptor.
     // If we performed a VM call, the descriptor has been popped already so
@@ -214,17 +243,18 @@ EmitBaselineLeaveStubFrame(MacroAssemble
     // Discard the frame descriptor.
     masm.loadPtr(Address(StackPointer, offsetof(BaselineStubFrame, descriptor)), ScratchRegister);
     masm.addPtr(Imm32(STUB_FRAME_SIZE), StackPointer);
 }
 
 inline void
 EmitIonLeaveStubFrame(MacroAssembler& masm)
 {
-    MOZ_CRASH("Not implemented yet.");
+    masm.Pop(ICStubReg);
+    masm.pop(ICTailCallReg); // See EmitIonEnterStubFrame for explanation on pop/Pop.
 }
 
 inline void
 EmitStowICValues(MacroAssembler& masm, int values)
 {
     MOZ_ASSERT(values >= 0 && values <= 2);
     switch(values) {
       case 1: