Bug 1417038 part 2 - Shrink ExitFooterFrame to one word. r=nbp

This commit is contained in:
Jan de Mooij 2017-11-15 14:39:39 +01:00
Родитель c35581ffc6
Коммит 1935a6bcca
13 изменённых файлов: 72 добавлений и 74 удалений

Просмотреть файл

@ -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);