Bug 950703 - SpiderMonkey: Use 32-bit slots on 64-bit platforms. r=jandem

This commit is contained in:
Dan Gohman 2013-12-17 08:46:37 -08:00
parent cc38af3736
commit 6367adde96
22 changed files with 187 additions and 148 deletions

View File

@ -5838,7 +5838,7 @@ StackDecrementForCall(MacroAssembler &masm, const VectorT &argTypes, unsigned ex
return AlignBytes(alreadyPushed + extraBytes + argBytes, StackAlignment) - alreadyPushed;
}
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * STACK_SLOT_SIZE +
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * sizeof(intptr_t) +
NonVolatileRegs.fpus().size() * sizeof(double);
static bool

View File

@ -32,6 +32,29 @@
namespace js {
namespace jit {
// Given a slot index, returns the offset, in bytes, of that slot from an
// IonJSFrameLayout. Slot distances are uniform across architectures, however,
// the distance does depend on the size of the frame header.
static inline int32_t
OffsetOfFrameSlot(int32_t slot)
{
if (slot <= 0)
return -slot;
return -(slot * STACK_SLOT_SIZE);
}
static inline uintptr_t
ReadFrameSlot(IonJSFrameLayout *fp, int32_t slot)
{
return *(uintptr_t *)((char *)fp + OffsetOfFrameSlot(slot));
}
static inline double
ReadFrameDoubleSlot(IonJSFrameLayout *fp, int32_t slot)
{
return *(double *)((char *)fp + OffsetOfFrameSlot(slot));
}
IonFrameIterator::IonFrameIterator(JSContext *cx)
: current_(cx->mainThread().ionTop),
type_(IonFrame_Exit),

View File

@ -17,6 +17,13 @@
namespace js {
namespace jit {
// The size of a stack "slot". Multiple adjacent slots are allocated together
// when larger stack allocations are needed.
static const uint32_t STACK_SLOT_SIZE = 4;
// The number of stack slots needed for a double value.
static const uint32_t DOUBLE_STACK_ALIGNMENT = 2;
typedef void * CalleeToken;
enum CalleeTokenTag
@ -310,29 +317,6 @@ namespace jit {
void
GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes);
// Given a slot index, returns the offset, in bytes, of that slot from an
// IonJSFrameLayout. Slot distances are uniform across architectures, however,
// the distance does depend on the size of the frame header.
static inline int32_t
OffsetOfFrameSlot(int32_t slot)
{
if (slot <= 0)
return -slot;
return -(slot * STACK_SLOT_SIZE);
}
static inline uintptr_t
ReadFrameSlot(IonJSFrameLayout *fp, int32_t slot)
{
return *(uintptr_t *)((char *)fp + OffsetOfFrameSlot(slot));
}
static inline double
ReadFrameDoubleSlot(IonJSFrameLayout *fp, int32_t slot)
{
return *(double *)((char *)fp + OffsetOfFrameSlot(slot));
}
CalleeToken
MarkCalleeToken(JSTracer *trc, CalleeToken token);

View File

@ -243,13 +243,13 @@ void
MacroAssembler::PushRegsInMask(RegisterSet set)
{
int32_t diffF = set.fpus().size() * sizeof(double);
int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
// On x86, always use push to push the integer registers, as it's fast
// on modern hardware and it's a small instruction.
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
Push(*iter);
}
#elif defined(JS_CPU_ARM)
@ -257,21 +257,21 @@ MacroAssembler::PushRegsInMask(RegisterSet set)
adjustFrame(diffG);
startDataTransferM(IsStore, StackPointer, DB, WriteBack);
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
transferReg(*iter);
}
finishDataTransfer();
} else {
reserveStack(diffG);
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
storePtr(*iter, Address(StackPointer, diffG));
}
}
#else
reserveStack(diffG);
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
storePtr(*iter, Address(StackPointer, diffG));
}
#endif
@ -293,7 +293,7 @@ MacroAssembler::PushRegsInMask(RegisterSet set)
void
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
{
int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
int32_t diffF = set.fpus().size() * sizeof(double);
const int32_t reservedG = diffG;
const int32_t reservedF = diffF;
@ -322,7 +322,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
// instruction.
if (ignore.empty(false)) {
for (GeneralRegisterForwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
Pop(*iter);
}
} else
@ -331,7 +331,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
if (set.gprs().size() > 1 && ignore.empty(false)) {
startDataTransferM(IsLoad, StackPointer, IA, WriteBack);
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
transferReg(*iter);
}
finishDataTransfer();
@ -340,7 +340,7 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
#endif
{
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
diffG -= STACK_SLOT_SIZE;
diffG -= sizeof(intptr_t);
if (!ignore.has(*iter))
loadPtr(Address(StackPointer, diffG), *iter);
}

View File

@ -37,7 +37,7 @@ class MSnapshot;
static const uint32_t VREG_INCREMENT = 1;
static const uint32_t THIS_FRAME_SLOT = 0;
static const uint32_t THIS_FRAME_ARGSLOT = 0;
#if defined(JS_NUNBOX32)
# define BOX_PIECES 2
@ -349,8 +349,7 @@ class LConstantIndex : public LAllocation
}
};
// Stack slots are indexes into the stack, given that each slot is size
// STACK_SLOT_SIZE.
// Stack slots are indices into the stack. The indices are byte indices.
class LStackSlot : public LAllocation
{
public:
@ -363,9 +362,7 @@ class LStackSlot : public LAllocation
}
};
// Arguments are reverse indexes into the stack, and as opposed to LStackSlot,
// each index is measured in bytes because we have to index the middle of a
// Value on 32 bits architectures.
// Arguments are reverse indices into the stack. The indices are byte indices.
class LArgument : public LAllocation
{
public:

View File

@ -799,6 +799,16 @@ LinearScanAllocator::allocateSlotFor(const LiveInterval *interval)
SlotList *freed;
if (reg->type() == LDefinition::DOUBLE)
freed = &finishedDoubleSlots_;
#if JS_BITS_PER_WORD == 64
else if (reg->type() == LDefinition::GENERAL ||
reg->type() == LDefinition::OBJECT ||
reg->type() == LDefinition::SLOTS)
freed = &finishedDoubleSlots_;
#endif
#ifdef JS_PUNBOX64
else if (reg->type() == LDefinition::BOX)
freed = &finishedDoubleSlots_;
#endif
#ifdef JS_NUNBOX32
else if (IsNunbox(reg))
freed = &finishedNunboxSlots_;
@ -882,6 +892,16 @@ LinearScanAllocator::freeAllocation(LiveInterval *interval, LAllocation *alloc)
if (alloc->isStackSlot()) {
if (mine->type() == LDefinition::DOUBLE)
finishedDoubleSlots_.append(interval);
#if JS_BITS_PER_WORD == 64
else if (mine->type() == LDefinition::GENERAL ||
mine->type() == LDefinition::OBJECT ||
mine->type() == LDefinition::SLOTS)
finishedDoubleSlots_.append(interval);
#endif
#ifdef JS_PUNBOX64
else if (mine->type() == LDefinition::BOX)
finishedDoubleSlots_.append(interval);
#endif
else
finishedSlots_.append(interval);
}

View File

@ -31,7 +31,7 @@ LIRGenerator::visitParameter(MParameter *param)
{
ptrdiff_t offset;
if (param->index() == MParameter::THIS_SLOT)
offset = THIS_FRAME_SLOT;
offset = THIS_FRAME_ARGSLOT;
else
offset = 1 + param->index();

View File

@ -69,16 +69,20 @@ class SnapshotReader
{
friend class SnapshotReader;
// An offset that is illegal for a local variable's stack allocation.
static const int32_t InvalidStackSlot = -1;
Register::Code reg_;
int32_t stackSlot_;
static Location From(const Register &reg) {
Location loc;
loc.reg_ = reg.code();
loc.stackSlot_ = INVALID_STACK_SLOT;
loc.stackSlot_ = InvalidStackSlot;
return loc;
}
static Location From(int32_t stackSlot) {
JS_ASSERT(stackSlot != InvalidStackSlot);
Location loc;
loc.reg_ = Register::Code(0); // Quell compiler warnings.
loc.stackSlot_ = stackSlot;
@ -95,7 +99,7 @@ class SnapshotReader
return stackSlot_;
}
bool isStackSlot() const {
return stackSlot_ != INVALID_STACK_SLOT;
return stackSlot_ != InvalidStackSlot;
}
};

View File

@ -28,10 +28,9 @@ class StackSlotAllocator
uint32_t allocateDoubleSlot() {
if (!doubleSlots.empty())
return doubleSlots.popCopy();
if (ComputeByteAlignment(height_, DOUBLE_STACK_ALIGNMENT))
if (height_ % 2 != 0)
normalSlots.append(++height_);
height_ += (sizeof(double) / STACK_SLOT_SIZE);
return height_;
return height_ += 2;
}
uint32_t allocateSlot() {
if (!normalSlots.empty())
@ -50,13 +49,20 @@ class StackSlotAllocator
void freeSlot(LDefinition::Type type, uint32_t index) {
switch (type) {
case LDefinition::FLOAT32:
#if JS_BITS_PER_WORD == 32
case LDefinition::GENERAL:
case LDefinition::OBJECT:
case LDefinition::SLOTS:
#endif
case LDefinition::FLOAT32: return freeSlot(index);
#if JS_BITS_PER_WORD == 64
case LDefinition::GENERAL:
case LDefinition::OBJECT:
case LDefinition::SLOTS:
#endif
#ifdef JS_PUNBOX64
case LDefinition::BOX:
#endif
case LDefinition::GENERAL: return freeSlot(index);
#ifdef JS_NUNBOX32
case LDefinition::TYPE:
case LDefinition::PAYLOAD:
@ -68,13 +74,20 @@ class StackSlotAllocator
uint32_t allocateSlot(LDefinition::Type type) {
switch (type) {
case LDefinition::FLOAT32:
#if JS_BITS_PER_WORD == 32
case LDefinition::GENERAL:
case LDefinition::OBJECT:
case LDefinition::SLOTS:
#endif
case LDefinition::FLOAT32: return allocateSlot();
#if JS_BITS_PER_WORD == 64
case LDefinition::GENERAL:
case LDefinition::OBJECT:
case LDefinition::SLOTS:
#endif
#ifdef JS_PUNBOX64
case LDefinition::BOX:
#endif
case LDefinition::GENERAL: return allocateSlot();
#ifdef JS_NUNBOX32
case LDefinition::TYPE:
case LDefinition::PAYLOAD:

View File

@ -17,18 +17,12 @@
namespace js {
namespace jit {
static const uint32_t STACK_SLOT_SIZE = 4;
static const uint32_t DOUBLE_STACK_ALIGNMENT = 2;
// In bytes: slots needed for potential memory->memory move spills.
// +8 for cycles
// +4 for gpr spills
// +8 for double spills
static const uint32_t ION_FRAME_SLACK_SIZE = 20;
// An offset that is illegal for a local variable's stack allocation.
static const int32_t INVALID_STACK_SLOT = -1;
// These offsets are specific to nunboxing, and capture offsets into the
// components of a js::Value.
static const int32_t NUNBOX32_TYPE_OFFSET = 4;

View File

@ -2211,7 +2211,7 @@ static inline uint32_t
GetArgStackDisp(uint32_t arg)
{
JS_ASSERT(arg >= NumIntArgRegs);
return (arg - NumIntArgRegs) * STACK_SLOT_SIZE;
return (arg - NumIntArgRegs) * sizeof(intptr_t);
}
#endif

View File

@ -34,7 +34,7 @@ BailoutEnvironment::BailoutEnvironment(JitCompartment *ion, void **sp)
if (bailout_->frameClass() != FrameSizeClass::None()) {
frameSize_ = bailout_->frameSize();
frame_ = &sp_[sizeof(BailoutStack) / STACK_SLOT_SIZE];
frame_ = &sp_[sizeof(BailoutStack) / sizeof(void *)];
// Compute the bailout ID.
IonCode *code = ion->getBailoutTable(bailout_->frameClass());
@ -49,14 +49,14 @@ BailoutEnvironment::BailoutEnvironment(JitCompartment *ion, void **sp)
JS_ASSERT(bailoutId_ < BAILOUT_TABLE_SIZE);
} else {
frameSize_ = bailout_->frameSize();
frame_ = &sp_[sizeof(ExtendedBailoutStack) / STACK_SLOT_SIZE];
frame_ = &sp_[sizeof(ExtendedBailoutStack) / sizeof(void *)];
}
}
IonFramePrefix *
BailoutEnvironment::top() const
{
return (IonFramePrefix *)&frame_[frameSize_ / STACK_SLOT_SIZE];
return (IonFramePrefix *)&frame_[frameSize_ / sizeof(void *)];
}
#endif

View File

@ -7,12 +7,13 @@
#ifndef jit_arm_IonFrames_arm_h
#define jit_arm_IonFrames_arm_h
#include <stdint.h>
#include "jit/shared/IonFrames-shared.h"
namespace js {
namespace jit {
class IonFramePrefix;
// Layout of the frame prefix. This assumes the stack architecture grows down.
// If this is ever not the case, we'll have to refactor.
class IonCommonFrameLayout
@ -50,26 +51,16 @@ class IonCommonFrameLayout
}
};
// this is the layout of the frame that is used when we enter Ion code from EABI code
class IonEntryFrameLayout : public IonCommonFrameLayout
class IonJSFrameLayout : public IonCommonFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonEntryFrameLayout);
}
};
class IonJSFrameLayout : public IonEntryFrameLayout
{
protected:
void *calleeToken_;
CalleeToken calleeToken_;
uintptr_t numActualArgs_;
public:
void *calleeToken() const {
CalleeToken calleeToken() const {
return calleeToken_;
}
void replaceCalleeToken(void *calleeToken) {
void replaceCalleeToken(CalleeToken calleeToken) {
calleeToken_ = calleeToken;
}
@ -113,6 +104,15 @@ class IonJSFrameLayout : public IonEntryFrameLayout
}
};
// this is the layout of the frame that is used when we enter Ion code from platform ABI code
class IonEntryFrameLayout : public IonJSFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonEntryFrameLayout);
}
};
class IonRectifierFrameLayout : public IonJSFrameLayout
{
public:
@ -121,13 +121,14 @@ class IonRectifierFrameLayout : public IonJSFrameLayout
}
};
class IonUnwoundRectifierFrameLayout : public IonJSFrameLayout
// The callee token is now dead.
class IonUnwoundRectifierFrameLayout : public IonRectifierFrameLayout
{
public:
static inline size_t Size() {
// On X86, there is a +sizeof(uintptr_t) to account for an extra callee token.
// This is not needed here because sizeof(IonExitFrame) == sizeof(IonRectifierFrame)
// due to extra padding.
// It is not necessary to accout for an extra callee token here because
// sizeof(IonExitFrameLayout) == sizeof(IonRectifierFrameLayout) due to
// extra padding.
return sizeof(IonUnwoundRectifierFrameLayout);
}
};
@ -159,43 +160,13 @@ class IonExitFooterFrame
}
};
class IonOsrFrameLayout : public IonJSFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonOsrFrameLayout);
}
};
class ICStub;
class IonBaselineStubFrameLayout : public IonCommonFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonBaselineStubFrameLayout);
}
static inline int reverseOffsetOfStubPtr() {
return -int(sizeof(void *));
}
static inline int reverseOffsetOfSavedFramePtr() {
return -int(2 * sizeof(void *));
}
inline ICStub *maybeStubPtr() {
uint8_t *fp = reinterpret_cast<uint8_t *>(this);
return *reinterpret_cast<ICStub **>(fp + reverseOffsetOfStubPtr());
}
};
class IonNativeExitFrameLayout;
class IonOOLNativeExitFrameLayout;
class IonOOLPropertyOpExitFrameLayout;
class IonOOLProxyExitFrameLayout;
class IonDOMExitFrameLayout;
// this is the frame layout when we are exiting ion code, and about to enter EABI code
// this is the frame layout when we are exiting ion code, and about to enter platform ABI code
class IonExitFrameLayout : public IonCommonFrameLayout
{
inline uint8_t *top() {
@ -273,6 +244,7 @@ class IonExitFrameLayout : public IonCommonFrameLayout
// IonExitFrameLayout.
class IonNativeExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
IonExitFooterFrame footer_;
IonExitFrameLayout exit_;
uintptr_t argc_;
@ -300,6 +272,7 @@ class IonNativeExitFrameLayout
class IonOOLNativeExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
IonExitFooterFrame footer_;
IonExitFrameLayout exit_;
@ -343,6 +316,7 @@ class IonOOLNativeExitFrameLayout
class IonOOLPropertyOpExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
IonExitFooterFrame footer_;
IonExitFrameLayout exit_;
@ -438,11 +412,12 @@ class IonOOLProxyExitFrameLayout
class IonDOMExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
IonExitFooterFrame footer_;
IonExitFrameLayout exit_;
JSObject *thisObj;
// We need to split the Value in 2 fields of 32 bits, otherwise the C++
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
// compiler may add some padding between the fields.
uint32_t loCalleeResult_;
uint32_t hiCalleeResult_;
@ -470,6 +445,7 @@ struct IonDOMMethodExitFrameLayoutTraits;
class IonDOMMethodExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
IonExitFooterFrame footer_;
IonExitFrameLayout exit_;
// This must be the last thing pushed, so as to stay common with
@ -478,7 +454,7 @@ class IonDOMMethodExitFrameLayout
Value *argv_;
uintptr_t argc_;
// We need to split the Value in 2 fields of 32 bits, otherwise the C++
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
// compiler may add some padding between the fields.
uint32_t loCalleeResult_;
uint32_t hiCalleeResult_;
@ -514,6 +490,36 @@ struct IonDOMMethodExitFrameLayoutTraits {
offsetof(IonDOMMethodExitFrameLayout, argv_);
};
class IonOsrFrameLayout : public IonJSFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonOsrFrameLayout);
}
};
class ICStub;
class IonBaselineStubFrameLayout : public IonCommonFrameLayout
{
public:
static inline size_t Size() {
return sizeof(IonBaselineStubFrameLayout);
}
static inline int reverseOffsetOfStubPtr() {
return -int(sizeof(void *));
}
static inline int reverseOffsetOfSavedFramePtr() {
return -int(2 * sizeof(void *));
}
inline ICStub *maybeStubPtr() {
uint8_t *fp = reinterpret_cast<uint8_t *>(this);
return *reinterpret_cast<ICStub **>(fp + reverseOffsetOfStubPtr());
}
};
// An invalidation bailout stack is at the stack pointer for the callee frame.
class InvalidationBailoutStack
{

View File

@ -2423,7 +2423,7 @@ MacroAssemblerARMCompat::cmpPtr(const Address &lhs, const ImmPtr &rhs)
void
MacroAssemblerARMCompat::setStackArg(const Register &reg, uint32_t arg)
{
ma_dataTransferN(IsStore, 32, true, sp, Imm32(arg * STACK_SLOT_SIZE), reg);
ma_dataTransferN(IsStore, 32, true, sp, Imm32(arg * sizeof(intptr_t)), reg);
}
@ -3640,8 +3640,8 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust)
if (!dynamicAlignment_) {
*stackAdjust += ComputeByteAlignment(framePushed_ + *stackAdjust, StackAlignment);
} else {
// STACK_SLOT_SIZE account for the saved stack pointer pushed by setupUnalignedABICall
*stackAdjust += ComputeByteAlignment(*stackAdjust + STACK_SLOT_SIZE, StackAlignment);
// sizeof(intptr_t) account for the saved stack pointer pushed by setupUnalignedABICall
*stackAdjust += ComputeByteAlignment(*stackAdjust + sizeof(intptr_t), StackAlignment);
}
reserveStack(*stackAdjust);

View File

@ -1143,22 +1143,22 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// The following functions are exposed for use in platform-shared code.
void Push(const Register &reg) {
ma_push(reg);
adjustFrame(STACK_SLOT_SIZE);
adjustFrame(sizeof(intptr_t));
}
void Push(const Imm32 imm) {
push(imm);
adjustFrame(STACK_SLOT_SIZE);
adjustFrame(sizeof(intptr_t));
}
void Push(const ImmWord imm) {
push(imm);
adjustFrame(STACK_SLOT_SIZE);
adjustFrame(sizeof(intptr_t));
}
void Push(const ImmPtr imm) {
Push(ImmWord(uintptr_t(imm.value)));
}
void Push(const ImmGCPtr ptr) {
push(ptr);
adjustFrame(STACK_SLOT_SIZE);
adjustFrame(sizeof(intptr_t));
}
void Push(const FloatRegister &t) {
VFPRegister r = VFPRegister(t);
@ -1176,19 +1176,19 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void PushWithPadding(const Register &reg, const Imm32 extraSpace) {
pushWithPadding(reg, extraSpace);
adjustFrame(STACK_SLOT_SIZE + extraSpace.value);
adjustFrame(sizeof(intptr_t) + extraSpace.value);
}
void PushWithPadding(const Imm32 imm, const Imm32 extraSpace) {
pushWithPadding(imm, extraSpace);
adjustFrame(STACK_SLOT_SIZE + extraSpace.value);
adjustFrame(sizeof(intptr_t) + extraSpace.value);
}
void Pop(const Register &reg) {
ma_pop(reg);
adjustFrame(-STACK_SLOT_SIZE);
adjustFrame(-sizeof(intptr_t));
}
void implicitPop(uint32_t args) {
JS_ASSERT(args % STACK_SLOT_SIZE == 0);
JS_ASSERT(args % sizeof(intptr_t) == 0);
adjustFrame(-args);
}
uint32_t framePushed() const {

View File

@ -14,9 +14,10 @@
namespace js {
namespace jit {
// Layout of the frame prefix. This assumes the stack architecture grows down.
// If this is ever not the case, we'll have to refactor.
class IonCommonFrameLayout
{
private:
uint8_t *returnAddress_;
uintptr_t descriptor_;
@ -52,15 +53,15 @@ class IonCommonFrameLayout
class IonJSFrameLayout : public IonCommonFrameLayout
{
void *calleeToken_;
CalleeToken calleeToken_;
uintptr_t numActualArgs_;
public:
CalleeToken calleeToken() const {
return calleeToken_;
}
void replaceCalleeToken(void *value) {
calleeToken_ = value;
void replaceCalleeToken(CalleeToken calleeToken) {
calleeToken_ = calleeToken;
}
static size_t offsetOfCalleeToken() {
@ -103,6 +104,7 @@ class IonJSFrameLayout : public IonCommonFrameLayout
}
};
// this is the layout of the frame that is used when we enter Ion code from platform ABI code
class IonEntryFrameLayout : public IonJSFrameLayout
{
public:
@ -124,6 +126,9 @@ class IonUnwoundRectifierFrameLayout : public IonRectifierFrameLayout
{
public:
static inline size_t Size() {
// It is not necessary to accout for an extra callee token here because
// sizeof(IonExitFrameLayout) == sizeof(IonRectifierFrameLayout) due to
// extra padding.
return sizeof(IonUnwoundRectifierFrameLayout);
}
};
@ -161,6 +166,7 @@ class IonOOLPropertyOpExitFrameLayout;
class IonOOLProxyExitFrameLayout;
class IonDOMExitFrameLayout;
// this is the frame layout when we are exiting ion code, and about to enter platform ABI code
class IonExitFrameLayout : public IonCommonFrameLayout
{
inline uint8_t *top() {
@ -234,6 +240,8 @@ class IonExitFrameLayout : public IonCommonFrameLayout
}
};
// Cannot inherit implementa<tion since we need to extend the top of
// IonExitFrameLayout.
class IonNativeExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
@ -241,7 +249,7 @@ class IonNativeExitFrameLayout
IonExitFrameLayout exit_;
uintptr_t argc_;
// We need to split the Value in 2 field of 32 bits, otherwise the C++
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
// compiler may add some padding between the fields.
uint32_t loCalleeResult_;
uint32_t hiCalleeResult_;
@ -284,7 +292,7 @@ class IonOOLNativeExitFrameLayout
public:
static inline size_t Size(size_t argc) {
// The Frame accounts for the callee/result and |this|, so we only needs args.
// The frame accounts for the callee/result and |this|, so we only need args.
return sizeof(IonOOLNativeExitFrameLayout) + (argc * sizeof(Value));
}
@ -409,7 +417,7 @@ class IonDOMExitFrameLayout
IonExitFrameLayout exit_;
JSObject *thisObj;
// We need to split the Value in 2 fields of 32 bits, otherwise the C++
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
// compiler may add some padding between the fields.
uint32_t loCalleeResult_;
uint32_t hiCalleeResult_;
@ -463,6 +471,7 @@ class IonDOMMethodExitFrameLayout
}
inline Value *vp() {
// The code in visitCallDOMNative depends on this static assert holding
JS_STATIC_ASSERT(offsetof(IonDOMMethodExitFrameLayout, loCalleeResult_) ==
(offsetof(IonDOMMethodExitFrameLayout, argc_) + sizeof(uintptr_t)));
return reinterpret_cast<Value*>(&loCalleeResult_);
@ -538,7 +547,7 @@ class InvalidationBailoutStack
void checkInvariants() const;
};
}
}
} // namespace jit
} // namespace js
#endif /* jit_shared_IonFrames_x86_shared_h */

View File

@ -198,7 +198,7 @@ class MacroAssemblerX86Shared : public Assembler
template <typename T>
void Push(const T &t) {
push(t);
framePushed_ += STACK_SLOT_SIZE;
framePushed_ += sizeof(intptr_t);
}
void Push(const FloatRegister &t) {
push(t);
@ -215,14 +215,14 @@ class MacroAssemblerX86Shared : public Assembler
template <typename T>
void Pop(const T &t) {
pop(t);
framePushed_ -= STACK_SLOT_SIZE;
framePushed_ -= sizeof(intptr_t);
}
void Pop(const FloatRegister &t) {
pop(t);
framePushed_ -= sizeof(double);
}
void implicitPop(uint32_t args) {
JS_ASSERT(args % STACK_SLOT_SIZE == 0);
JS_ASSERT(args % sizeof(intptr_t) == 0);
framePushed_ -= args;
}
uint32_t framePushed() const {

View File

@ -12,9 +12,6 @@
namespace js {
namespace jit {
static const ptrdiff_t STACK_SLOT_SIZE = 8;
static const uint32_t DOUBLE_STACK_ALIGNMENT = 1;
// In bytes: slots needed for potential memory->memory move spills.
// +8 for cycles
// +8 for gpr spills
@ -27,9 +24,6 @@ static const uint32_t ShadowStackSpace = 32;
static const uint32_t ShadowStackSpace = 0;
#endif
// An offset that is illegal for a local variable's stack allocation.
static const int32_t INVALID_STACK_SLOT = -1;
class Registers {
public:
typedef JSC::X86Registers::RegisterID Code;

View File

@ -198,7 +198,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t *stackAdjust)
if (dynamicAlignment_) {
*stackAdjust = stackForCall_
+ ComputeByteAlignment(stackForCall_ + STACK_SLOT_SIZE,
+ ComputeByteAlignment(stackForCall_ + sizeof(intptr_t),
StackAlignment);
} else {
*stackAdjust = stackForCall_

View File

@ -11,8 +11,6 @@
namespace js {
namespace jit {
static const ptrdiff_t STACK_SLOT_SIZE = 4;
static const uint32_t DOUBLE_STACK_ALIGNMENT = 2;
// In bytes: slots needed for potential memory->memory move spills.
// +8 for cycles
@ -23,9 +21,6 @@ static const uint32_t ION_FRAME_SLACK_SIZE = 20;
// Only Win64 requires shadow stack space.
static const uint32_t ShadowStackSpace = 0;
// An offset that is illegal for a local variable's stack allocation.
static const int32_t INVALID_STACK_SLOT = -1;
// These offsets are specific to nunboxing, and capture offsets into the
// components of a js::Value.
static const int32_t NUNBOX32_TYPE_OFFSET = 4;

View File

@ -196,7 +196,7 @@ MacroAssemblerX86::callWithABIPre(uint32_t *stackAdjust)
if (dynamicAlignment_) {
*stackAdjust = stackForCall_
+ ComputeByteAlignment(stackForCall_ + STACK_SLOT_SIZE,
+ ComputeByteAlignment(stackForCall_ + sizeof(intptr_t),
StackAlignment);
} else {
*stackAdjust = stackForCall_

View File

@ -676,7 +676,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
}
void setStackArg(const Register &reg, uint32_t arg) {
movl(reg, Operand(esp, arg * STACK_SLOT_SIZE));
movl(reg, Operand(esp, arg * sizeof(intptr_t)));
}
// Type testing instructions can take a tag in a register or a