Bug 1184965 part 5 - Factor MacroAssembler::buildFakeExitFrame. r=h4writer

This commit is contained in:
Nicolas B. Pierron 2015-09-01 11:58:46 +02:00
parent 15b3d63278
commit 919bcb91e7
12 changed files with 111 additions and 112 deletions

View File

@ -2872,8 +2872,7 @@ CodeGenerator::visitCallNative(LCallNative* call)
masm.Push(argUintNReg);
// Construct native exit frame.
uint32_t safepointOffset;
masm.buildFakeExitFrame(tempReg, &safepointOffset);
uint32_t safepointOffset = masm.buildFakeExitFrame(tempReg);
masm.enterFakeExitFrame(NativeExitFrameLayout::Token());
markSafepointAt(safepointOffset, call);
@ -2991,8 +2990,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
masm.moveStackPtrTo(argObj);
// Construct native exit frame.
uint32_t safepointOffset;
masm.buildFakeExitFrame(argJSContext, &safepointOffset);
uint32_t safepointOffset = masm.buildFakeExitFrame(argJSContext);
masm.enterFakeExitFrame(IonDOMMethodExitFrameLayout::Token());
markSafepointAt(safepointOffset, call);
@ -9735,8 +9733,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty* ins)
// Rooting will happen at GC time.
masm.moveStackPtrTo(ObjectReg);
uint32_t safepointOffset;
masm.buildFakeExitFrame(JSContextReg, &safepointOffset);
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
masm.enterFakeExitFrame(IonDOMExitFrameLayout::GetterToken());
markSafepointAt(safepointOffset, ins);
@ -9825,8 +9822,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty* ins)
// Rooting will happen at GC time.
masm.moveStackPtrTo(ObjectReg);
uint32_t safepointOffset;
masm.buildFakeExitFrame(JSContextReg, &safepointOffset);
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
masm.enterFakeExitFrame(IonDOMExitFrameLayout::SetterToken());
markSafepointAt(safepointOffset, ins);

View File

@ -180,6 +180,25 @@ MacroAssembler::makeFrameDescriptor(Register frameSizeReg, FrameType type)
orPtr(Imm32(type), frameSizeReg);
}
void
MacroAssembler::pushStaticFrameDescriptor(FrameType type)
{
uint32_t descriptor = MakeFrameDescriptor(framePushed(), type);
Push(Imm32(descriptor));
}
uint32_t
MacroAssembler::buildFakeExitFrame(Register scratch)
{
mozilla::DebugOnly<uint32_t> initialDepth = framePushed();
pushStaticFrameDescriptor(JitFrame_IonJS);
uint32_t retAddr = pushFakeReturnAddress(scratch);
MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
return retAddr;
}
//}}} check_macroassembler_style
// ===============================================================

View File

@ -577,6 +577,29 @@ class MacroAssembler : public MacroAssemblerSpecific
// calling the Jit function. It is a composite value defined in JitFrames.h
inline void makeFrameDescriptor(Register frameSizeReg, FrameType type);
// Push the frame descriptor, based on the statically known framePushed.
inline void pushStaticFrameDescriptor(FrameType type);
// This function emulates a call by pushing an exit frame on the stack,
// except that the fake-function is inlined within the body of the caller.
//
// This function assumes that the current frame is an IonJS frame.
//
// This function returns the offset of the /fake/ return address, in order to use
// the return address to index the safepoints, which are used to list all
// live registers.
//
// This function should be balanced with a call to adjustStack, to pop the
// exit frame and emulate the return statement of the inlined function.
inline uint32_t buildFakeExitFrame(Register scratch);
private:
// This function is used by buildFakeExitFrame to push a fake return address
// on the stack. This fake return address should never be used for resuming
// any execution, and can even be an invalid pointer into the instruction
// stream, as long as it does not alias any other.
uint32_t pushFakeReturnAddress(Register scratch) PER_SHARED_ARCH;
//}}} check_macroassembler_style
public:

View File

@ -1865,31 +1865,6 @@ MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32
return ma_vstr(src, Address(scratch, offset), cc);
}
void
MacroAssemblerARMCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
{
DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
asMasm().Push(Imm32(descriptor)); // descriptor_
enterNoPool(2);
DebugOnly<uint32_t> offsetBeforePush = currentOffset();
asMasm().Push(pc); // actually pushes $pc + 8.
// Consume an additional 4 bytes. The start of the next instruction will
// then be 8 bytes after the instruction for Push(pc); this offset can
// therefore be fed to the safepoint.
ma_nop();
uint32_t pseudoReturnOffset = currentOffset();
leaveNoPool();
MOZ_ASSERT(asMasm().framePushed() == initialDepth + ExitFrameLayout::Size());
MOZ_ASSERT(pseudoReturnOffset - offsetBeforePush == 8);
*offset = pseudoReturnOffset;
}
bool
MacroAssemblerARMCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
{
@ -5266,4 +5241,25 @@ MacroAssembler::callJitNoProfiler(Register callee)
return currentOffset();
}
uint32_t
MacroAssembler::pushFakeReturnAddress(Register scratch)
{
// On ARM any references to the pc, adds an additional 8 to it, which
// correspond to 2 instructions of 4 bytes. Thus we use an additional nop
// to pad until we reach the pushed pc.
//
// Note: In practice this should not be necessary, as this fake return
// address is never used for resuming any execution. Thus theoriticaly we
// could just do a Push(pc), and ignore the nop as well as the pool.
enterNoPool(2);
DebugOnly<uint32_t> offsetBeforePush = currentOffset();
Push(pc); // actually pushes $pc + 8.
ma_nop();
uint32_t pseudoReturnOffset = currentOffset();
leaveNoPool();
MOZ_ASSERT(pseudoReturnOffset - offsetBeforePush == 8);
return pseudoReturnOffset;
}
//}}} check_macroassembler_style

View File

@ -1194,10 +1194,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// Common interface.
/////////////////////////////////////////////////////////////////
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 add32(Register src, Register dest);
void add32(Imm32 imm, Register dest);
void add32(Imm32 imm, const Address& dest);

View File

@ -36,27 +36,6 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
Csel(dest, dest, wzr, GreaterThan);
}
void
MacroAssemblerCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
{
mozilla::DebugOnly<uint32_t> initialDepth = framePushed();
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
asMasm().Push(Imm32(descriptor)); // descriptor_
enterNoPool(3);
Label fakeCallsite;
Adr(ARMRegister(scratch, 64), &fakeCallsite);
asMasm().Push(scratch);
bind(&fakeCallsite);
uint32_t pseudoReturnOffset = currentOffset();
leaveNoPool();
MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
*offset = pseudoReturnOffset;
}
void
MacroAssembler::alignFrameForICArguments(MacroAssembler::AfterICSaveLive& aic)
{
@ -612,6 +591,21 @@ MacroAssembler::callJitNoProfiler(Register callee)
return currentOffset();
}
uint32_t
MacroAssembler::pushFakeReturnAddress(Register scratch)
{
enterNoPool(3);
Label fakeCallsite;
Adr(ARMRegister(scratch, 64), &fakeCallsite);
Push(scratch);
bind(&fakeCallsite);
uint32_t pseudoReturnOffset = currentOffset();
leaveNoPool();
return = pseudoReturnOffset;
}
//}}} check_macroassembler_style
} // namespace jit

View File

@ -2659,10 +2659,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
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 appendCallSite(const CallSiteDesc& desc) {
MOZ_CRASH("appendCallSite");
}

View File

@ -1498,25 +1498,6 @@ MacroAssemblerMIPS::ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* label,
branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
}
void
MacroAssemblerMIPSCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
{
mozilla::DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
CodeLabel cl;
ma_li(scratch, cl.dest());
uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
asMasm().Push(Imm32(descriptor));
asMasm().Push(scratch);
bind(cl.src());
*offset = currentOffset();
MOZ_ASSERT(asMasm().framePushed() == initialDepth + ExitFrameLayout::Size());
addCodeLabel(cl);
}
bool
MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
{
@ -3596,4 +3577,18 @@ MacroAssembler::callJitNoProfiler(Register callee)
return currentOffset();
}
uint32_t
MacroAssembler::pushFakeReturnAddress(Register scratch)
{
CodeLabel cl;
ma_li(scratch, cl.dest());
Push(scratch);
bind(cl.src());
uint32_t retAddr = currentOffset();
addCodeLabel(cl);
return retAddr;
}
//}}} check_macroassembler_style

View File

@ -1112,10 +1112,6 @@ public:
MOZ_CRASH("NYI");
}
// 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 add32(Register src, Register dest);
void add32(Imm32 imm, Register dest);
void add32(Imm32 imm, const Address& dest);

View File

@ -1358,8 +1358,7 @@ CodeGeneratorShared::callVM(const VMFunction& fun, LInstruction* ins, const Regi
masm.makeFrameDescriptor(*dynStack, JitFrame_IonJS);
masm.Push(*dynStack); // descriptor
} else {
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
masm.Push(Imm32(descriptor));
masm.pushStaticFrameDescriptor(JitFrame_IonJS);
}
// Call the wrapper function. The wrapper is in charge to unwind the stack

View File

@ -63,27 +63,6 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
bind(&done);
}
// Builds an exit frame on the stack, with a return address to an internal
// non-function. Returns offset to be passed to markSafepointAt().
void
MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t* offset)
{
mozilla::DebugOnly<uint32_t> initialDepth = asMasm().framePushed();
CodeLabel cl;
mov(cl.dest(), scratch);
uint32_t descriptor = MakeFrameDescriptor(asMasm().framePushed(), JitFrame_IonJS);
asMasm().Push(Imm32(descriptor));
asMasm().Push(scratch);
bind(cl.src());
*offset = currentOffset();
MOZ_ASSERT(asMasm().framePushed() == initialDepth + ExitFrameLayout::Size());
addCodeLabel(cl);
}
void
MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic)
{
@ -402,4 +381,18 @@ MacroAssembler::callJitNoProfiler(Register callee)
return currentOffset();
}
uint32_t
MacroAssembler::pushFakeReturnAddress(Register scratch)
{
CodeLabel cl;
mov(cl.dest(), scratch);
Push(scratch);
bind(cl.src());
uint32_t retAddr = currentOffset();
addCodeLabel(cl);
return retAddr;
}
//}}} check_macroassembler_style

View File

@ -1473,10 +1473,6 @@ class MacroAssemblerX86Shared : public Assembler
lea(Operand(address), dest);
}
// 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 callAndPushReturnAddress(Label* label);
void checkStackAlignment() {