Bug 1184965 part 6 - Move MacroAssembler ExitFrameFooter function in the check_macroassembler_style section. r=jandem

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

View File

@ -319,7 +319,7 @@ AsmJSModule::finish(ExclusiveContext* cx, TokenStream& tokenStream, MacroAssembl
MOZ_ASSERT(masm.jumpRelocationTableBytes() == 0);
MOZ_ASSERT(masm.dataRelocationTableBytes() == 0);
MOZ_ASSERT(masm.preBarrierTableBytes() == 0);
MOZ_ASSERT(!masm.hasEnteredExitFrame());
MOZ_ASSERT(!masm.hasSelfReference());
// Copy over metadata, making sure to update all offsets on ARM.

View File

@ -10365,7 +10365,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
EmitBaselineCreateStubFrameDescriptor(masm, scratch);
masm.push(scratch);
masm.push(ICTailCallReg);
masm.enterFakeExitFrame(NativeExitFrameLayout::Token());
masm.enterFakeExitFrame(NativeExitFrameLayoutToken);
// Execute call.
masm.setupUnalignedABICall(scratch);
@ -10463,7 +10463,7 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
EmitBaselineCreateStubFrameDescriptor(masm, scratch);
masm.push(scratch);
masm.push(ICTailCallReg);
masm.enterFakeExitFrame(NativeExitFrameLayout::Token());
masm.enterFakeExitFrame(NativeExitFrameLayoutToken);
// Execute call.
masm.setupUnalignedABICall(scratch);

View File

@ -2873,7 +2873,7 @@ CodeGenerator::visitCallNative(LCallNative* call)
// Construct native exit frame.
uint32_t safepointOffset = masm.buildFakeExitFrame(tempReg);
masm.enterFakeExitFrame(NativeExitFrameLayout::Token());
masm.enterFakeExitFrame(NativeExitFrameLayoutToken);
markSafepointAt(safepointOffset, call);
@ -2991,7 +2991,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
// Construct native exit frame.
uint32_t safepointOffset = masm.buildFakeExitFrame(argJSContext);
masm.enterFakeExitFrame(IonDOMMethodExitFrameLayout::Token());
masm.enterFakeExitFrame(IonDOMMethodExitFrameLayoutToken);
markSafepointAt(safepointOffset, call);
@ -6311,7 +6311,7 @@ JitRuntime::generateLazyLinkStub(JSContext* cx)
size_t convertToExitFrame = JitFrameLayout::Size() - ExitFrameLayout::Size();
masm.addPtr(Imm32(convertToExitFrame << FRAMESIZE_SHIFT), descriptor);
masm.enterFakeExitFrame(LazyLinkExitFrameLayout::Token());
masm.enterFakeExitFrame(LazyLinkExitFrameLayoutToken);
masm.PushStubCode();
masm.setupUnalignedABICall(temp0);
@ -9734,7 +9734,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty* ins)
masm.moveStackPtrTo(ObjectReg);
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
masm.enterFakeExitFrame(IonDOMExitFrameLayout::GetterToken());
masm.enterFakeExitFrame(IonDOMExitFrameLayoutGetterToken);
markSafepointAt(safepointOffset, ins);
@ -9823,7 +9823,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty* ins)
masm.moveStackPtrTo(ObjectReg);
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
masm.enterFakeExitFrame(IonDOMExitFrameLayout::SetterToken());
masm.enterFakeExitFrame(IonDOMExitFrameLayoutSetterToken);
markSafepointAt(safepointOffset, ins);

View File

@ -945,7 +945,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm,
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayoutToken);
// Construct and execute call.
masm.setupUnalignedABICall(scratchReg);
@ -1003,7 +1003,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm,
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLPropertyOpExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLPropertyOpExitFrameLayoutToken);
// Make the call.
masm.setupUnalignedABICall(scratchReg);
@ -1586,7 +1586,7 @@ EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayoutToken);
// Make the call.
masm.setupUnalignedABICall(scratch);
@ -2297,7 +2297,7 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayoutToken);
// Make the call.
masm.setupUnalignedABICall(scratch);
@ -2506,7 +2506,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLNativeExitFrameLayoutToken);
// Make the call
masm.setupUnalignedABICall(scratchReg);
@ -2570,7 +2570,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
return false;
masm.enterFakeExitFrame(IonOOLSetterOpExitFrameLayout::Token());
masm.enterFakeExitFrame(IonOOLSetterOpExitFrameLayoutToken);
// Make the call.
masm.setupUnalignedABICall(scratchReg);

View File

@ -199,30 +199,32 @@ MacroAssembler::buildFakeExitFrame(Register scratch)
return retAddr;
}
//}}} check_macroassembler_style
// ===============================================================
// Exit frame footer.
void
MacroAssembler::PushStubCode()
{
exitCodePatch_ = PushWithPatch(ImmWord(-1));
// Make sure that we do not erase an existing self-reference.
MOZ_ASSERT(!hasSelfReference());
selfReferencePatch_ = PushWithPatch(ImmWord(-1));
}
void
MacroAssembler::enterExitFrame(const VMFunction* f)
{
linkExitFrame();
// Push the ioncode. (Bailout or VM wrapper)
// Push the JitCode pointer. (Keep the code alive, when on the stack)
PushStubCode();
// Push VMFunction pointer, to mark arguments.
Push(ImmPtr(f));
}
void
MacroAssembler::enterFakeExitFrame(JitCode* codeVal)
MacroAssembler::enterFakeExitFrame(enum ExitFrameTokenValues token)
{
linkExitFrame();
Push(ImmPtr(codeVal));
Push(Imm32(token));
Push(ImmPtr(nullptr));
}
@ -233,11 +235,14 @@ MacroAssembler::leaveExitFrame(size_t extraFrame)
}
bool
MacroAssembler::hasEnteredExitFrame() const
MacroAssembler::hasSelfReference() const
{
return exitCodePatch_.offset() != 0;
return selfReferencePatch_.offset() != 0;
}
//}}} check_macroassembler_style
// ===============================================================
} // namespace jit
} // namespace js

View File

@ -1588,15 +1588,6 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output)
bind(&done);
}
// Save an exit frame (which must be aligned to the stack pointer) to
// PerThreadData::jitTop of the main thread.
void
MacroAssembler::linkExitFrame()
{
AbsoluteAddress jitTop(GetJitContext()->runtime->addressOfJitTop());
storeStackPtr(jitTop);
}
static void
BailoutReportOverRecursed(JSContext* cx)
{
@ -1667,7 +1658,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
push(temp);
push(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeAddr)));
// No GC things to mark on the stack, push a bare token.
enterFakeExitFrame(ExitFrameLayout::BareToken());
enterFakeExitFrame(ExitFrameLayoutBareToken);
// If monitorStub is non-null, handle resumeAddr appropriately.
Label noMonitor;
@ -2365,16 +2356,7 @@ void
MacroAssembler::link(JitCode* code)
{
MOZ_ASSERT(!oom());
// If this code can transition to C++ code and witness a GC, then we need to store
// the JitCode onto the stack in order to GC it correctly. exitCodePatch should
// be unset if the code never needed to push its JitCode*.
if (hasEnteredExitFrame()) {
exitCodePatch_.fixup(this);
PatchDataWithValueCheck(CodeLocationLabel(code, exitCodePatch_),
ImmPtr(code),
ImmPtr((void*)-1));
}
linkSelfReference(code);
linkProfilerCallSites(code);
}
@ -2879,6 +2861,30 @@ MacroAssembler::callWithABINoProfiler(AsmJSImmPtr imm, MoveOp::Type result)
callWithABIPost(stackAdjust, result);
}
// ===============================================================
// Exit frame footer.
void
MacroAssembler::linkExitFrame()
{
AbsoluteAddress jitTop(GetJitContext()->runtime->addressOfJitTop());
storeStackPtr(jitTop);
}
void
MacroAssembler::linkSelfReference(JitCode* code)
{
// If this code can transition to C++ code and witness a GC, then we need to store
// the JitCode onto the stack in order to GC it correctly. exitCodePatch should
// be unset if the code never needed to push its JitCode*.
if (hasSelfReference()) {
selfReferencePatch_.fixup(this);
PatchDataWithValueCheck(CodeLocationLabel(code, selfReferencePatch_),
ImmPtr(code),
ImmPtr((void*)-1));
}
}
//}}} check_macroassembler_style
namespace js {

View File

@ -172,6 +172,9 @@
namespace js {
namespace jit {
// Defined in JitFrames.h
enum ExitFrameTokenValues;
// The public entrypoint for emitting assembly. Note that a MacroAssembler can
// use cx->lifoAlloc, so take care not to interleave masm use with other
// lifoAlloc use if one will be destroyed before the other.
@ -600,6 +603,50 @@ class MacroAssembler : public MacroAssemblerSpecific
// stream, as long as it does not alias any other.
uint32_t pushFakeReturnAddress(Register scratch) PER_SHARED_ARCH;
public:
// ===============================================================
// Exit frame footer.
//
// When calling outside the Jit we push an exit frame. To mark the stack
// correctly, we have to push additional information, called the Exit frame
// footer, which is used to identify how the stack is marked.
//
// See JitFrames.h, and MarkJitExitFrame in JitFrames.cpp.
// If the current piece of code might be garbage collected, then the exit
// frame footer must contain a pointer to the current JitCode, such that the
// garbage collector can keep the code alive as long this code is on the
// stack. This function pushes a placeholder which is replaced when the code
// is linked.
inline void PushStubCode();
// Return true if the code contains a self-reference which needs to be
// patched when the code is linked.
inline bool hasSelfReference() const;
// Push stub code and the VMFunction pointer.
inline void enterExitFrame(const VMFunction* f = nullptr);
// Push an exit frame token to identify which fake exit frame this footer
// corresponds to.
inline void enterFakeExitFrame(enum ExitFrameTokenValues token);
// Pop ExitFrame footer in addition to the extra frame.
inline void leaveExitFrame(size_t extraFrame = 0);
private:
// Save the top of the stack into PerThreadData::jitTop of the main thread,
// which should be the location of the latest exit frame.
void linkExitFrame();
// Patch the value of PushStubCode with the pointer to the finalized code.
void linkSelfReference(JitCode* code);
// If the JitCode that created this assembler needs to transition into the VM,
// we want to store the JitCode on the stack in order to mark it during a GC.
// This is a reference to a patch location where the JitCode* will be written.
CodeOffsetLabel selfReferencePatch_;
//}}} check_macroassembler_style
public:
@ -1095,30 +1142,7 @@ class MacroAssembler : public MacroAssemblerSpecific
void compareStrings(JSOp op, Register left, Register right, Register result,
Label* fail);
// If the JitCode that created this assembler needs to transition into the VM,
// we want to store the JitCode on the stack in order to mark it during a GC.
// This is a reference to a patch location where the JitCode* will be written.
private:
CodeOffsetLabel exitCodePatch_;
private:
void linkExitFrame();
public:
inline void PushStubCode();
// Push stub code, and the VMFunction pointer.
inline void enterExitFrame(const VMFunction* f = nullptr);
// The JitCode * argument here is one of the tokens defined in the various
// exit frame layout classes, e.g. NativeExitFrameLayout::Token().
inline void enterFakeExitFrame(JitCode* codeVal);
// Pop ExitFrame footer in addition to the extra frame.
inline void leaveExitFrame(size_t extraFrame = 0);
inline bool hasEnteredExitFrame() const;
// Generates code used to complete a bailout.
void generateBailoutTail(Register scratch, Register bailoutInfo);

View File

@ -287,7 +287,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.push(scratch);
masm.push(Imm32(0)); // Fake return address.
// No GC things to mark on the stack, push a bare token.
masm.enterFakeExitFrame(ExitFrameLayout::BareToken());
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
masm.push(framePtr); // BaselineFrame
masm.push(r0); // jitcode

View File

@ -189,7 +189,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.makeFrameDescriptor(r19, JitFrame_BaselineJS);
masm.asVIXL().Push(x19, xzr); // Push xzr for a fake return address.
// No GC things to mark: push a bare token.
masm.enterFakeExitFrame(ExitFrameLayout::BareToken());
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
masm.push(BaselineFrameReg, reg_code);

View File

@ -241,7 +241,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.storePtr(zero, Address(StackPointer, 0)); // fake return address
// No GC things to mark, push a bare token.
masm.enterFakeExitFrame(ExitFrameLayout::BareToken());
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
masm.reserveStack(2 * sizeof(uintptr_t));
masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame

View File

@ -226,7 +226,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.push(valuesSize);
masm.push(Imm32(0)); // Fake return address.
// No GC things to mark, push a bare token.
masm.enterFakeExitFrame(ExitFrameLayout::BareToken());
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
regs.add(valuesSize);

View File

@ -219,7 +219,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.push(scratch); // Fake return address.
masm.push(Imm32(0));
// No GC things to mark on the stack, push a bare token.
masm.enterFakeExitFrame(ExitFrameLayout::BareToken());
masm.enterFakeExitFrame(ExitFrameLayoutBareToken);
masm.push(framePtr);
masm.push(jitcode);