diff --git a/js/src/jit/x64/MacroAssembler-x64.cpp b/js/src/jit/x64/MacroAssembler-x64.cpp index 6374dd6c64..83904c3a97 100644 --- a/js/src/jit/x64/MacroAssembler-x64.cpp +++ b/js/src/jit/x64/MacroAssembler-x64.cpp @@ -425,13 +425,32 @@ MacroAssembler::subFromStackPtr(Imm32 imm32) // Ion frame data for a piece of code is very large. To handle this special case, // for frames over 1k in size we allocate memory on the stack incrementally, touching // it as we go. + // + // When the amount is quite large, which it can be, we emit an actual loop, in order + // to keep the function prologue compact. Compactness is a requirement for e.g. + // Wasm's CodeRange data structure, which can encode only 8-bit offsets. uint32_t amountLeft = imm32.value; - while (amountLeft > 4096) { + uint32_t fullPages = amountLeft / 4096; + if (fullPages <= 8) { + while (amountLeft > 4096) { + subq(Imm32(4096), StackPointer); + store32(Imm32(0), Address(StackPointer, 0)); + amountLeft -= 4096; + } + subq(Imm32(amountLeft), StackPointer); + } else { + ScratchRegisterScope scratch(*this); + Label top; + move32(Imm32(fullPages), scratch); + bind(&top); subq(Imm32(4096), StackPointer); store32(Imm32(0), Address(StackPointer, 0)); - amountLeft -= 4096; + subl(Imm32(1), scratch); + j(Assembler::NonZero, &top); + amountLeft -= fullPages * 4096; + if (amountLeft) + subq(Imm32(amountLeft), StackPointer); } - subq(Imm32(amountLeft), StackPointer); } } diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index fbefd9e77a..22ce86984d 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -339,13 +339,39 @@ MacroAssembler::subFromStackPtr(Imm32 imm32) // Ion frame data for a piece of code is very large. To handle this special case, // for frames over 1k in size we allocate memory on the stack incrementally, touching // it as we go. + // + // When the amount is quite large, which it can be, we emit an actual loop, in order + // to keep the function prologue compact. Compactness is a requirement for e.g. + // Wasm's CodeRange data structure, which can encode only 8-bit offsets. uint32_t amountLeft = imm32.value; - while (amountLeft > 4096) { + uint32_t fullPages = amountLeft / 4096; + if (fullPages <= 8) { + while (amountLeft > 4096) { + subl(Imm32(4096), StackPointer); + store32(Imm32(0), Address(StackPointer, 0)); + amountLeft -= 4096; + } + subl(Imm32(amountLeft), StackPointer); + } else { + // Save scratch register. + push(eax); + amountLeft -= 4; + fullPages = amountLeft / 4096; + + Label top; + move32(Imm32(fullPages), eax); + bind(&top); subl(Imm32(4096), StackPointer); store32(Imm32(0), Address(StackPointer, 0)); - amountLeft -= 4096; + subl(Imm32(1), eax); + j(Assembler::NonZero, &top); + amountLeft -= fullPages * 4096; + if (amountLeft) + subl(Imm32(amountLeft), StackPointer); + + // Restore scratch register. + movl(Operand(StackPointer, uint32_t(imm32.value) - 4), eax); } - subl(Imm32(amountLeft), StackPointer); } } diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp index a40134fdf3..4d6085b960 100644 --- a/js/src/wasm/WasmCode.cpp +++ b/js/src/wasm/WasmCode.cpp @@ -400,11 +400,11 @@ CodeRange::CodeRange(uint32_t funcIndex, uint32_t funcLineOrBytecode, FuncOffset { MOZ_ASSERT(begin_ < profilingReturn_); MOZ_ASSERT(profilingReturn_ < end_); - MOZ_ASSERT(funcBeginToTableEntry_ == offsets.tableEntry - begin_); - MOZ_ASSERT(funcBeginToTableProfilingJump_ == offsets.tableProfilingJump - begin_); - MOZ_ASSERT(funcBeginToNonProfilingEntry_ == offsets.nonProfilingEntry - begin_); - MOZ_ASSERT(funcProfilingJumpToProfilingReturn_ == profilingReturn_ - offsets.profilingJump); - MOZ_ASSERT(funcProfilingEpilogueToProfilingReturn_ == profilingReturn_ - offsets.profilingEpilogue); + MOZ_ASSERT(offsets.tableEntry - begin_ <= UINT8_MAX); + MOZ_ASSERT(offsets.tableProfilingJump - begin_ <= UINT8_MAX); + MOZ_ASSERT(offsets.nonProfilingEntry - begin_ <= UINT8_MAX); + MOZ_ASSERT(profilingReturn_ - offsets.profilingJump <= UINT8_MAX); + MOZ_ASSERT(profilingReturn_ - offsets.profilingEpilogue <= UINT8_MAX); } static size_t