mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1184965 part 5 - Factor MacroAssembler::buildFakeExitFrame. r=h4writer
This commit is contained in:
parent
15b3d63278
commit
919bcb91e7
@ -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);
|
||||
|
@ -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
|
||||
// ===============================================================
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user