diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 15baf7bee34e..20ad0db4317d 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -1394,7 +1394,20 @@ class LIRGraph localSlotCount_ = localSlotCount; } uint32_t localSlotCount() const { - return AlignBytes(localSlotCount_, StackAlignment / STACK_SLOT_SIZE); + return localSlotCount_; + } + // Return the localSlotCount() value rounded up so that it satisfies the + // platform stack alignment requirement, and so that it's a multiple of + // the number of slots per Value. + uint32_t paddedLocalSlotCount() const { + // Round to StackAlignment, but also round to at least sizeof(Value) in + // 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); + } + size_t paddedLocalSlotsSize() const { + return paddedLocalSlotCount() * STACK_SLOT_SIZE; } void setArgumentSlotCount(uint32_t argumentSlotCount) { argumentSlotCount_ = argumentSlotCount; @@ -1402,8 +1415,12 @@ class LIRGraph uint32_t argumentSlotCount() const { 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 localSlotCount() + (argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE); + return paddedLocalSlotCount() + (argumentsSize() / STACK_SLOT_SIZE); } bool addConstantToPool(const Value &v, uint32_t *index); size_t numConstants() const { diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 410af5d2b062..4441b399e9a7 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -49,8 +49,7 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph, Mac sps_(&GetIonContext()->runtime->spsProfiler(), &lastPC_), osrEntryOffset_(0), skipArgCheckEntryOffset_(0), - frameDepth_(graph->localSlotCount() * sizeof(STACK_SLOT_SIZE) + - graph->argumentSlotCount() * sizeof(Value)) + frameDepth_(graph->paddedLocalSlotsSize() + graph->argumentsSize()) { if (!gen->compilingAsmJS()) masm.setInstrumentation(&sps_); diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index f2bc4f82d894..f174640cf459 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -170,16 +170,17 @@ class CodeGeneratorShared : public LInstructionVisitor // A slot of 0 is permitted only to calculate %esp offset for calls. JS_ASSERT(slot >= 0 && slot <= int32_t(graph.argumentSlotCount())); int32_t offset = masm.framePushed() - - (graph.localSlotCount() * STACK_SLOT_SIZE) - + graph.paddedLocalSlotsSize() - (slot * sizeof(Value)); + // Passed arguments go below A function's local stack storage. // When arguments are being pushed, there is nothing important on the stack. // Therefore, It is safe to push the arguments down arbitrarily. Pushing - // by 8 is desirable since everything on the stack is a Value, which is 8 - // bytes large. - - offset &= ~7; + // by sizeof(Value) is desirable since everything on the stack is a Value. + // Note that paddedLocalSlotCount() aligns to at least a Value boundary + // specifically to support this. JS_ASSERT(offset >= 0); + JS_ASSERT(offset % sizeof(Value) == 0); return offset; }