Bug 950703 - SpiderMonkey: Make stack slots byte-indexed. r=jandem

This commit is contained in:
Dan Gohman 2013-12-17 08:49:15 -08:00
parent b3cf21af4f
commit 3ebe2c9229
10 changed files with 40 additions and 52 deletions

View File

@ -221,8 +221,7 @@ struct IonScript
uint32_t safepointsStart_;
uint32_t safepointsSize_;
// Number of STACK_SLOT_SIZE-length slots this function reserves on the
// stack.
// Number of bytes this function reserves on the stack.
uint32_t frameSlots_;
// Frame size is the value that can be added to the StackPointer along

View File

@ -38,9 +38,7 @@ namespace jit {
static inline int32_t
OffsetOfFrameSlot(int32_t slot)
{
if (slot <= 0)
return -slot;
return -(slot * STACK_SLOT_SIZE);
return -slot;
}
static inline uintptr_t

View File

@ -19,13 +19,6 @@
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
@ -391,7 +384,7 @@ class IonJSFrameLayout : public IonCommonFrameLayout
// Computes a reference to a slot, where a slot is a distance from the base
// frame pointer (as would be used for LStackSlot).
uintptr_t *slotRef(uint32_t slot) {
return (uintptr_t *)((uint8_t *)this - (slot * STACK_SLOT_SIZE));
return (uintptr_t *)((uint8_t *)this - slot);
}
static inline size_t Size() {

View File

@ -1436,10 +1436,10 @@ class LIRGraph
// case that's greater, because StackOffsetOfPassedArg rounds argument
// slots to 8-byte boundaries.
size_t Alignment = Max(sizeof(StackAlignment), sizeof(Value));
return AlignBytes(localSlotCount(), Alignment / STACK_SLOT_SIZE);
return AlignBytes(localSlotCount(), Alignment);
}
size_t paddedLocalSlotsSize() const {
return paddedLocalSlotCount() * STACK_SLOT_SIZE;
return paddedLocalSlotCount();
}
void setArgumentSlotCount(uint32_t argumentSlotCount) {
argumentSlotCount_ = argumentSlotCount;
@ -1448,11 +1448,10 @@ class LIRGraph
return argumentSlotCount_;
}
size_t argumentsSize() const {
JS_STATIC_ASSERT(sizeof(Value) >= size_t(STACK_SLOT_SIZE));
return argumentSlotCount() * sizeof(Value);
}
uint32_t totalSlotCount() const {
return paddedLocalSlotCount() + (argumentsSize() / STACK_SLOT_SIZE);
return paddedLocalSlotCount() + argumentsSize();
}
bool addConstantToPool(const Value &v, uint32_t *index);
size_t numConstants() const {
@ -1610,8 +1609,8 @@ static inline unsigned
OffsetOfNunboxSlot(LDefinition::Type type)
{
if (type == LDefinition::PAYLOAD)
return NUNBOX32_PAYLOAD_OFFSET / STACK_SLOT_SIZE;
return NUNBOX32_TYPE_OFFSET / STACK_SLOT_SIZE;
return NUNBOX32_PAYLOAD_OFFSET;
return NUNBOX32_TYPE_OFFSET;
}
// Note that stack indexes for LStackSlot are modelled backwards, so a
@ -1620,8 +1619,8 @@ static inline unsigned
BaseOfNunboxSlot(LDefinition::Type type, unsigned slot)
{
if (type == LDefinition::PAYLOAD)
return slot + (NUNBOX32_PAYLOAD_OFFSET / STACK_SLOT_SIZE);
return slot + (NUNBOX32_TYPE_OFFSET / STACK_SLOT_SIZE);
return slot + NUNBOX32_PAYLOAD_OFFSET;
return slot + NUNBOX32_TYPE_OFFSET;
}
#endif

View File

@ -20,7 +20,7 @@ using mozilla::FloorLog2;
bool
SafepointWriter::init(TempAllocator &alloc, uint32_t slotCount)
{
frameSlots_ = BitSet::New(alloc, slotCount);
frameSlots_ = BitSet::New(alloc, slotCount / sizeof(intptr_t));
if (!frameSlots_)
return false;
@ -99,10 +99,13 @@ MapSlotsToBitset(BitSet *set, CompactBufferWriter &stream, uint32_t nslots, uint
set->clear();
for (uint32_t i = 0; i < nslots; i++) {
// Slots are represented at a distance from |fp|. Since the stack grows
// down, this means slots start at index 1, so we subtract 1 to pack
// the bitset.
set->insert(slots[i] - 1);
// Slots are represented at a distance from |fp|. We divide by the
// pointer size, since we only care about pointer-sized/aligned slots
// here. Since the stack grows down, this means slots start at index 1,
// so we subtract 1 to pack the bitset.
JS_ASSERT(slots[i] % sizeof(intptr_t) == 0);
JS_ASSERT(slots[i] / sizeof(intptr_t) > 0);
set->insert(slots[i] / sizeof(intptr_t) - 1);
}
size_t count = set->rawLength();
@ -334,7 +337,7 @@ SafepointWriter::endEntry()
SafepointReader::SafepointReader(IonScript *script, const SafepointIndex *si)
: stream_(script->safepoints() + si->safepointOffset(),
script->safepoints() + script->safepointsSize()),
frameSlots_(script->frameSlots())
frameSlots_(script->frameSlots() / sizeof(intptr_t))
{
osiCallPointOffset_ = stream_.readUnsigned();
@ -397,8 +400,9 @@ SafepointReader::getSlotFromBitmap(uint32_t *slot)
currentSlotChunk_ &= ~(1 << bit);
// Return the slot, taking care to add 1 back in since it was subtracted
// when added in the original bitset.
*slot = ((nextSlotChunkNumber_ - 1) * BitSet::BitsPerWord) + bit + 1;
// when added in the original bitset, and re-scale it by the pointer size,
// reversing the transformation in MapSlotsToBitset.
*slot = (((nextSlotChunkNumber_ - 1) * BitSet::BitsPerWord) + bit + 1) * sizeof(intptr_t);
return true;
}

View File

@ -28,19 +28,19 @@ class StackSlotAllocator
uint32_t allocateDoubleSlot() {
if (!doubleSlots.empty())
return doubleSlots.popCopy();
if (height_ % 2 != 0)
normalSlots.append(++height_);
return height_ += 2;
if (height_ % 8 != 0)
normalSlots.append(height_ += 4);
return height_ += 8;
}
uint32_t allocateSlot() {
if (!normalSlots.empty())
return normalSlots.popCopy();
if (!doubleSlots.empty()) {
uint32_t index = doubleSlots.popCopy();
normalSlots.append(index - 1);
normalSlots.append(index - 4);
return index;
}
return ++height_;
return height_ += 4;
}
public:

View File

@ -14,11 +14,7 @@ using namespace js::jit;
static inline uint32_t
DefaultStackSlot(uint32_t vreg)
{
#if JS_BITS_PER_WORD == 32
return vreg * 2 + 2;
#else
return vreg + 1;
#endif
return vreg * sizeof(Value);
}
LAllocation *
@ -243,7 +239,7 @@ StupidAllocator::go()
// not track liveness we cannot determine that two vregs have disjoint
// lifetimes. Thus, the maximum stack height is the number of vregs (scaled
// by two on 32 bit platforms to allow storing double values).
graph.setLocalSlotCount(DefaultStackSlot(graph.numVirtualRegisters() - 1) + 1);
graph.setLocalSlotCount(DefaultStackSlot(graph.numVirtualRegisters()));
if (!init())
return false;

View File

@ -2148,7 +2148,7 @@ GetIntArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *paddi
uint32_t doubleSlots = Max(0, (int32_t)usedFloatArgs - (int32_t)NumFloatArgRegs);
doubleSlots *= 2;
int intSlots = usedIntArgs - NumIntArgRegs;
return (intSlots + doubleSlots + *padding) * STACK_SLOT_SIZE;
return (intSlots + doubleSlots + *padding) * sizeof(intptr_t);
}
static inline uint32_t
@ -2159,7 +2159,7 @@ GetFloat32ArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *p
if (usedIntArgs > NumIntArgRegs)
intSlots = usedIntArgs - NumIntArgRegs;
uint32_t float32Slots = usedFloatArgs - NumFloatArgRegs;
return (intSlots + float32Slots + *padding) * STACK_SLOT_SIZE;
return (intSlots + float32Slots + *padding) * sizeof(intptr_t);
}
static inline uint32_t
@ -2174,7 +2174,7 @@ GetDoubleArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *pa
}
uint32_t doubleSlots = usedFloatArgs - NumFloatArgRegs;
doubleSlots *= 2;
return (intSlots + doubleSlots + *padding) * STACK_SLOT_SIZE;
return (intSlots + doubleSlots + *padding) * sizeof(intptr_t);
}
#else
static inline bool

View File

@ -3632,10 +3632,10 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust)
{
JS_ASSERT(inCall_);
#ifdef JS_CPU_ARM_HARDFP
*stackAdjust = ((usedIntSlots_ > NumIntArgRegs) ? usedIntSlots_ - NumIntArgRegs : 0) * STACK_SLOT_SIZE;
*stackAdjust += 2*((usedFloatSlots_ > NumFloatArgRegs) ? usedFloatSlots_ - NumFloatArgRegs : 0) * STACK_SLOT_SIZE;
*stackAdjust = ((usedIntSlots_ > NumIntArgRegs) ? usedIntSlots_ - NumIntArgRegs : 0) * sizeof(intptr_t);
*stackAdjust += 2*((usedFloatSlots_ > NumFloatArgRegs) ? usedFloatSlots_ - NumFloatArgRegs : 0) * sizeof(intptr_t);
#else
*stackAdjust = ((usedSlots_ > NumIntArgRegs) ? usedSlots_ - NumIntArgRegs : 0) * STACK_SLOT_SIZE;
*stackAdjust = ((usedSlots_ > NumIntArgRegs) ? usedSlots_ - NumIntArgRegs : 0) * sizeof(intptr_t);
#endif
if (!dynamicAlignment_) {
*stackAdjust += ComputeByteAlignment(framePushed_ + *stackAdjust, StackAlignment);

View File

@ -150,7 +150,7 @@ class CodeGeneratorShared : public LInstructionVisitor
inline int32_t SlotToStackOffset(int32_t slot) const {
JS_ASSERT(slot > 0 && slot <= int32_t(graph.localSlotCount()));
int32_t offset = masm.framePushed() - (slot * STACK_SLOT_SIZE);
int32_t offset = masm.framePushed() - slot;
JS_ASSERT(offset >= 0);
return offset;
}
@ -158,11 +158,10 @@ class CodeGeneratorShared : public LInstructionVisitor
// See: SlotToStackOffset. This is used to convert pushed arguments
// to a slot index that safepoints can use.
//
// offset = framePushed - (slot * STACK_SLOT_SIZE)
// offset + (slot * STACK_SLOT_SIZE) = framePushed
// slot * STACK_SLOT_SIZE = framePushed - offset
// slot = (framePushed - offset) / STACK_SLOT_SIZE
return (masm.framePushed() - offset) / STACK_SLOT_SIZE;
// offset = framePushed - slot
// offset + slot = framePushed
// slot = framePushed - offset
return masm.framePushed() - offset;
}
// For argument construction for calls. Argslots are Value-sized.