mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 950703 - SpiderMonkey: Use 32-bit slots on 64-bit platforms. r=jandem
This commit is contained in:
parent
cc38af3736
commit
6367adde96
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 ®) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -2423,7 +2423,7 @@ MacroAssemblerARMCompat::cmpPtr(const Address &lhs, const ImmPtr &rhs)
|
||||
void
|
||||
MacroAssemblerARMCompat::setStackArg(const Register ®, 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);
|
||||
|
@ -1143,22 +1143,22 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
// The following functions are exposed for use in platform-shared code.
|
||||
void Push(const Register ®) {
|
||||
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 ®, 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 ®) {
|
||||
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 {
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
|
@ -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_
|
||||
|
@ -676,7 +676,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
}
|
||||
|
||||
void setStackArg(const Register ®, 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
|
||||
|
Loading…
Reference in New Issue
Block a user