зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1417038 part 2 - Shrink ExitFooterFrame to one word. r=nbp
This commit is contained in:
Родитель
c35581ffc6
Коммит
1935a6bcca
|
@ -4170,7 +4170,7 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative* call)
|
|||
// Construct native exit frame.
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(argJSContext);
|
||||
masm.loadJSContext(argJSContext);
|
||||
masm.enterFakeExitFrame(argJSContext, argJSContext, ExitFrameToken::IonDOMMethod);
|
||||
masm.enterFakeExitFrame(argJSContext, argJSContext, ExitFrameType::IonDOMMethod);
|
||||
|
||||
markSafepointAt(safepointOffset, call);
|
||||
|
||||
|
@ -8048,7 +8048,7 @@ JitRuntime::generateLazyLinkStub(JSContext* cx)
|
|||
Register temp0 = regs.takeAny();
|
||||
|
||||
masm.loadJSContext(temp0);
|
||||
masm.enterFakeExitFrame(temp0, temp0, ExitFrameToken::LazyLink);
|
||||
masm.enterFakeExitFrame(temp0, temp0, ExitFrameType::LazyLink);
|
||||
masm.PushStubCode();
|
||||
|
||||
masm.setupUnalignedABICall(temp0);
|
||||
|
@ -11668,7 +11668,7 @@ CodeGenerator::visitGetDOMProperty(LGetDOMProperty* ins)
|
|||
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
|
||||
masm.loadJSContext(JSContextReg);
|
||||
masm.enterFakeExitFrame(JSContextReg, JSContextReg, ExitFrameToken::IonDOMGetter);
|
||||
masm.enterFakeExitFrame(JSContextReg, JSContextReg, ExitFrameType::IonDOMGetter);
|
||||
|
||||
markSafepointAt(safepointOffset, ins);
|
||||
|
||||
|
@ -11767,7 +11767,7 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty* ins)
|
|||
|
||||
uint32_t safepointOffset = masm.buildFakeExitFrame(JSContextReg);
|
||||
masm.loadJSContext(JSContextReg);
|
||||
masm.enterFakeExitFrame(JSContextReg, JSContextReg, ExitFrameToken::IonDOMSetter);
|
||||
masm.enterFakeExitFrame(JSContextReg, JSContextReg, ExitFrameType::IonDOMSetter);
|
||||
|
||||
markSafepointAt(safepointOffset, ins);
|
||||
|
||||
|
|
|
@ -1093,7 +1093,7 @@ IonCacheIRCompiler::emitCallNativeGetterResult()
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(GetReturnAddressToIonCode(cx_), save))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameToken::IonOOLNative);
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameType::IonOOLNative);
|
||||
|
||||
// Construct and execute call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
@ -1151,7 +1151,7 @@ IonCacheIRCompiler::emitCallProxyGetResult()
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(GetReturnAddressToIonCode(cx_), save))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameToken::IonOOLProxy);
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameType::IonOOLProxy);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
@ -2004,7 +2004,7 @@ IonCacheIRCompiler::emitCallNativeSetter()
|
|||
|
||||
if (!masm.icBuildOOLFakeExitFrame(GetReturnAddressToIonCode(cx_), save))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameToken::IonOOLNative);
|
||||
masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameType::IonOOLNative);
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(scratch);
|
||||
|
|
|
@ -786,7 +786,7 @@ EnsureBareExitFrame(JSContext* cx, JitFrameLayout* frame)
|
|||
#endif
|
||||
|
||||
cx->activation()->asJit()->setJSExitFP((uint8_t*)frame);
|
||||
*exitFrame->footer()->addressOfJitCode() = ExitFrameLayout::BareToken();
|
||||
exitFrame->footer()->setBareExitFrame();
|
||||
MOZ_ASSERT(exitFrame->isBareExit());
|
||||
}
|
||||
|
||||
|
@ -1100,13 +1100,6 @@ TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame)
|
|||
{
|
||||
ExitFooterFrame* footer = frame.exitFrame()->footer();
|
||||
|
||||
// Trace the code of the code handling the exit path. This is needed because
|
||||
// invalidated script are no longer traced because data are erased by the
|
||||
// invalidation and relocation data are no longer reliable. So the VM
|
||||
// wrapper or the invalidation code may be GC if no JitCode keep reference
|
||||
// on them.
|
||||
MOZ_ASSERT(uintptr_t(footer->jitCode()) != uintptr_t(-1));
|
||||
|
||||
// This corresponds to the case where we have build a fake exit frame which
|
||||
// handles the case of a native function call. We need to trace the argument
|
||||
// vector of the function call, and also new.target if it was a constructing
|
||||
|
@ -1174,8 +1167,7 @@ TraceJitExitFrame(JSTracer* trc, const JSJitFrameIter& frame)
|
|||
MOZ_ASSERT(frame.exitFrame()->isWrapperExit());
|
||||
|
||||
const VMFunction* f = footer->function();
|
||||
if (f == nullptr)
|
||||
return;
|
||||
MOZ_ASSERT(f);
|
||||
|
||||
// Trace arguments of the VM wrapper.
|
||||
uint8_t* argBase = frame.exitFrame()->argBase();
|
||||
|
|
|
@ -468,24 +468,45 @@ class IonICCallFrameLayout : public CommonFrameLayout
|
|||
}
|
||||
};
|
||||
|
||||
enum class ExitFrameType : uint8_t
|
||||
{
|
||||
CallNative = 0x0,
|
||||
ConstructNative = 0x1,
|
||||
IonDOMGetter = 0x2,
|
||||
IonDOMSetter = 0x3,
|
||||
IonDOMMethod = 0x4,
|
||||
IonOOLNative = 0x5,
|
||||
IonOOLProxy = 0x6,
|
||||
VMFunction = 0xFD,
|
||||
LazyLink = 0xFE,
|
||||
Bare = 0xFF,
|
||||
};
|
||||
|
||||
// GC related data used to keep alive data surrounding the Exit frame.
|
||||
class ExitFooterFrame
|
||||
{
|
||||
const VMFunction* function_;
|
||||
JitCode* jitCode_;
|
||||
// Stores the ExitFrameType or, for ExitFrameType::VMFunction, the
|
||||
// VMFunction*.
|
||||
uintptr_t data_;
|
||||
|
||||
public:
|
||||
static inline size_t Size() {
|
||||
return sizeof(ExitFooterFrame);
|
||||
}
|
||||
inline JitCode* jitCode() const {
|
||||
return jitCode_;
|
||||
void setBareExitFrame() {
|
||||
data_ = uintptr_t(ExitFrameType::Bare);
|
||||
}
|
||||
inline JitCode** addressOfJitCode() {
|
||||
return &jitCode_;
|
||||
ExitFrameType type() const {
|
||||
static_assert(sizeof(ExitFrameType) == sizeof(uint8_t),
|
||||
"Code assumes ExitFrameType fits in a byte");
|
||||
if (data_ > UINT8_MAX)
|
||||
return ExitFrameType::VMFunction;
|
||||
MOZ_ASSERT(ExitFrameType(data_) != ExitFrameType::VMFunction);
|
||||
return ExitFrameType(data_);
|
||||
}
|
||||
inline const VMFunction* function() const {
|
||||
return function_;
|
||||
MOZ_ASSERT(type() == ExitFrameType::VMFunction);
|
||||
return reinterpret_cast<const VMFunction*>(data_);
|
||||
}
|
||||
|
||||
// This should only be called for function()->outParam == Type_Handle
|
||||
|
@ -502,20 +523,6 @@ class IonOOLNativeExitFrameLayout;
|
|||
class IonOOLProxyExitFrameLayout;
|
||||
class IonDOMExitFrameLayout;
|
||||
|
||||
enum class ExitFrameToken : uint8_t
|
||||
{
|
||||
CallNative = 0x0,
|
||||
ConstructNative = 0x1,
|
||||
IonDOMGetter = 0x2,
|
||||
IonDOMSetter = 0x3,
|
||||
IonDOMMethod = 0x4,
|
||||
IonOOLNative = 0x5,
|
||||
IonOOLProxy = 0x8,
|
||||
VMFunction = 0xFD,
|
||||
LazyLink = 0xFE,
|
||||
Bare = 0xFF
|
||||
};
|
||||
|
||||
// this is the frame layout when we are exiting ion code, and about to enter platform ABI code
|
||||
class ExitFrameLayout : public CommonFrameLayout
|
||||
{
|
||||
|
@ -526,8 +533,8 @@ class ExitFrameLayout : public CommonFrameLayout
|
|||
public:
|
||||
// Pushed for "bare" fake exit frames that have no GC things on stack to be
|
||||
// traced.
|
||||
static JitCode* BareToken() { return (JitCode*)ExitFrameToken::Bare; }
|
||||
static JitCode* VMFunctionToken() { return (JitCode*)ExitFrameToken::VMFunction; }
|
||||
static ExitFrameType BareType() { return ExitFrameType::Bare; }
|
||||
static ExitFrameType VMFunctionType() { return ExitFrameType::VMFunction; }
|
||||
|
||||
static inline size_t Size() {
|
||||
return sizeof(ExitFrameLayout);
|
||||
|
@ -545,20 +552,20 @@ class ExitFrameLayout : public CommonFrameLayout
|
|||
// each wrapper are pushed before the exit frame. This correspond exactly
|
||||
// to the value of the argBase register of the generateVMWrapper function.
|
||||
inline uint8_t* argBase() {
|
||||
MOZ_ASSERT(footer()->jitCode() != nullptr);
|
||||
MOZ_ASSERT(isWrapperExit());
|
||||
return top();
|
||||
}
|
||||
|
||||
inline bool isWrapperExit() {
|
||||
return footer()->jitCode() == VMFunctionToken();
|
||||
return footer()->type() == ExitFrameType::VMFunction;
|
||||
}
|
||||
inline bool isBareExit() {
|
||||
return footer()->jitCode() == BareToken();
|
||||
return footer()->type() == ExitFrameType::Bare;
|
||||
}
|
||||
|
||||
// See the various exit frame layouts below.
|
||||
template <typename T> inline bool is() {
|
||||
return footer()->jitCode() == T::Token();
|
||||
return footer()->type() == T::Type();
|
||||
}
|
||||
template <typename T> inline T* as() {
|
||||
MOZ_ASSERT(this->is<T>());
|
||||
|
@ -599,13 +606,13 @@ class NativeExitFrameLayout
|
|||
class CallNativeExitFrameLayout : public NativeExitFrameLayout
|
||||
{
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::CallNative; }
|
||||
static ExitFrameType Type() { return ExitFrameType::CallNative; }
|
||||
};
|
||||
|
||||
class ConstructNativeExitFrameLayout : public NativeExitFrameLayout
|
||||
{
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::ConstructNative; }
|
||||
static ExitFrameType Type() { return ExitFrameType::ConstructNative; }
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -636,7 +643,7 @@ class IonOOLNativeExitFrameLayout
|
|||
uint32_t hiThis_;
|
||||
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::IonOOLNative; }
|
||||
static ExitFrameType Type() { return ExitFrameType::IonOOLNative; }
|
||||
|
||||
static inline size_t Size(size_t argc) {
|
||||
// The frame accounts for the callee/result and |this|, so we only need args.
|
||||
|
@ -686,7 +693,7 @@ class IonOOLProxyExitFrameLayout
|
|||
JitCode* stubCode_;
|
||||
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::IonOOLProxy; }
|
||||
static ExitFrameType Type() { return ExitFrameType::IonOOLProxy; }
|
||||
|
||||
static inline size_t Size() {
|
||||
return sizeof(IonOOLProxyExitFrameLayout);
|
||||
|
@ -723,8 +730,8 @@ class IonDOMExitFrameLayout
|
|||
uint32_t hiCalleeResult_;
|
||||
|
||||
public:
|
||||
static JitCode* GetterToken() { return (JitCode*)ExitFrameToken::IonDOMGetter; }
|
||||
static JitCode* SetterToken() { return (JitCode*)ExitFrameToken::IonDOMSetter; }
|
||||
static ExitFrameType GetterType() { return ExitFrameType::IonDOMGetter; }
|
||||
static ExitFrameType SetterType() { return ExitFrameType::IonDOMSetter; }
|
||||
|
||||
static inline size_t Size() {
|
||||
return sizeof(IonDOMExitFrameLayout);
|
||||
|
@ -763,7 +770,7 @@ class IonDOMMethodExitFrameLayout
|
|||
friend struct IonDOMMethodExitFrameLayoutTraits;
|
||||
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::IonDOMMethod; }
|
||||
static ExitFrameType Type() { return ExitFrameType::IonDOMMethod; }
|
||||
|
||||
static inline size_t Size() {
|
||||
return sizeof(IonDOMMethodExitFrameLayout);
|
||||
|
@ -790,18 +797,18 @@ class IonDOMMethodExitFrameLayout
|
|||
inline bool
|
||||
IonDOMExitFrameLayout::isMethodFrame()
|
||||
{
|
||||
return footer_.jitCode() == IonDOMMethodExitFrameLayout::Token();
|
||||
return footer_.type() == IonDOMMethodExitFrameLayout::Type();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool
|
||||
ExitFrameLayout::is<IonDOMExitFrameLayout>()
|
||||
{
|
||||
JitCode* code = footer()->jitCode();
|
||||
ExitFrameType type = footer()->type();
|
||||
return
|
||||
code == IonDOMExitFrameLayout::GetterToken() ||
|
||||
code == IonDOMExitFrameLayout::SetterToken() ||
|
||||
code == IonDOMMethodExitFrameLayout::Token();
|
||||
type == IonDOMExitFrameLayout::GetterType() ||
|
||||
type == IonDOMExitFrameLayout::SetterType() ||
|
||||
type == IonDOMMethodExitFrameLayout::Type();
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -828,7 +835,7 @@ class LazyLinkExitFrameLayout
|
|||
JitFrameLayout exit_;
|
||||
|
||||
public:
|
||||
static JitCode* Token() { return (JitCode*)ExitFrameToken::LazyLink; }
|
||||
static ExitFrameType Type() { return ExitFrameType::LazyLink; }
|
||||
|
||||
static inline size_t Size() {
|
||||
return sizeof(LazyLinkExitFrameLayout);
|
||||
|
|
|
@ -315,25 +315,24 @@ MacroAssembler::PushStubCode()
|
|||
void
|
||||
MacroAssembler::enterExitFrame(Register cxreg, Register scratch, const VMFunction* f)
|
||||
{
|
||||
MOZ_ASSERT(f);
|
||||
linkExitFrame(cxreg, scratch);
|
||||
Push(Imm32(int32_t(ExitFrameToken::VMFunction)));
|
||||
// Push VMFunction pointer, to mark arguments.
|
||||
Push(ImmPtr(f));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::enterFakeExitFrame(Register cxreg, Register scratch, ExitFrameToken token)
|
||||
MacroAssembler::enterFakeExitFrame(Register cxreg, Register scratch, ExitFrameType type)
|
||||
{
|
||||
linkExitFrame(cxreg, scratch);
|
||||
Push(Imm32(int32_t(token)));
|
||||
Push(ImmPtr(nullptr));
|
||||
Push(Imm32(int32_t(type)));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::enterFakeExitFrameForNative(Register cxreg, Register scratch, bool isConstructing)
|
||||
{
|
||||
enterFakeExitFrame(cxreg, scratch, isConstructing ? ExitFrameToken::ConstructNative
|
||||
: ExitFrameToken::CallNative);
|
||||
enterFakeExitFrame(cxreg, scratch, isConstructing ? ExitFrameType::ConstructNative
|
||||
: ExitFrameType::CallNative);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1505,7 +1505,7 @@ void
|
|||
MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
||||
{
|
||||
loadJSContext(scratch);
|
||||
enterExitFrame(scratch, scratch);
|
||||
enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
Label baseline;
|
||||
|
||||
|
@ -1568,7 +1568,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
|
|||
push(Address(bailoutInfo, offsetof(BaselineBailoutInfo, resumeAddr)));
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
loadJSContext(scratch);
|
||||
enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
// If monitorStub is non-null, handle resumeAddr appropriately.
|
||||
Label noMonitor;
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace js {
|
|||
namespace jit {
|
||||
|
||||
// Defined in JitFrames.h
|
||||
enum class ExitFrameToken : uint8_t;
|
||||
enum class ExitFrameType : uint8_t;
|
||||
|
||||
class AutoSaveLiveRegisters;
|
||||
|
||||
|
@ -712,11 +712,11 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
inline bool hasSelfReference() const;
|
||||
|
||||
// Push stub code and the VMFunction pointer.
|
||||
inline void enterExitFrame(Register cxreg, Register scratch, const VMFunction* f = nullptr);
|
||||
inline void enterExitFrame(Register cxreg, Register scratch, const VMFunction* f);
|
||||
|
||||
// Push an exit frame token to identify which fake exit frame this footer
|
||||
// corresponds to.
|
||||
inline void enterFakeExitFrame(Register cxreg, Register scratch, ExitFrameToken token);
|
||||
inline void enterFakeExitFrame(Register cxreg, Register scratch, ExitFrameType type);
|
||||
|
||||
// Push an exit frame token for a native call.
|
||||
inline void enterFakeExitFrameForNative(Register cxreg, Register scratch, bool isConstructing);
|
||||
|
|
|
@ -287,7 +287,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
masm.push(Imm32(0)); // Fake return address.
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
masm.loadJSContext(scratch);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
masm.push(framePtr); // BaselineFrame
|
||||
masm.push(r0); // jitcode
|
||||
|
|
|
@ -190,7 +190,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
masm.asVIXL().Push(x19, xzr); // Push xzr for a fake return address.
|
||||
// No GC things to mark: push a bare token.
|
||||
masm.loadJSContext(r19);
|
||||
masm.enterFakeExitFrame(r19, r19, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(r19, r19, ExitFrameType::Bare);
|
||||
|
||||
masm.push(BaselineFrameReg, reg_code);
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.loadJSContext(scratch);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
masm.reserveStack(2 * sizeof(uintptr_t));
|
||||
masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
|
||||
|
|
|
@ -278,7 +278,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.loadJSContext(scratch);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
masm.reserveStack(2 * sizeof(uintptr_t));
|
||||
masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
|
||||
|
|
|
@ -231,7 +231,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
masm.push(Imm32(0)); // Fake return address.
|
||||
// No GC things to mark, push a bare token.
|
||||
masm.loadJSContext(scratch);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
regs.add(valuesSize);
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ JitRuntime::generateEnterJIT(JSContext* cx)
|
|||
masm.push(Imm32(0));
|
||||
// No GC things to mark on the stack, push a bare token.
|
||||
masm.loadJSContext(scratch);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameToken::Bare);
|
||||
masm.enterFakeExitFrame(scratch, scratch, ExitFrameType::Bare);
|
||||
|
||||
masm.push(framePtr);
|
||||
masm.push(jitcode);
|
||||
|
|
Загрузка…
Ссылка в новой задаче