diff --git a/js/src/ion/AsmJS.cpp b/js/src/ion/AsmJS.cpp index d3e85591549..bb5c808868e 100644 --- a/js/src/ion/AsmJS.cpp +++ b/js/src/ion/AsmJS.cpp @@ -4912,10 +4912,14 @@ CheckFunctionBodiesParallel(ModuleCompiler &m) } #endif // JS_PARALLEL_COMPILATION -static RegisterSet AllRegs = RegisterSet(GeneralRegisterSet(Registers::AllMask), - FloatRegisterSet(FloatRegisters::AllMask)); -static RegisterSet NonVolatileRegs = RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask), - FloatRegisterSet(FloatRegisters::NonVolatileMask)); +// All registers except the stack pointer. +static const RegisterSet AllRegsExceptSP = + RegisterSet(GeneralRegisterSet(Registers::AllMask & + ~(uint32_t(1) << Registers::StackPointer)), + FloatRegisterSet(FloatRegisters::AllMask)); +static const RegisterSet NonVolatileRegs = + RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask), + FloatRegisterSet(FloatRegisters::NonVolatileMask)); static void LoadAsmJSActivationIntoRegister(MacroAssembler &masm, Register reg) @@ -5496,12 +5500,12 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel) // The operation-callback exit is called from arbitrarily-interrupted asm.js // code. That means we must first save *all* registers and restore *all* -// registers when we resume. The address to resume to (assuming that -// js_HandleExecutionInterrupt doesn't indicate that the execution should be -// aborted) is stored in AsmJSActivation::resumePC_. Unfortunately, loading -// this requires a scratch register which we don't have after restoring all -// registers. To hack around this, push the resumePC on the stack so that it -// can be popped directly into PC. +// registers (except the stack pointer) when we resume. The address to resume to +// (assuming that js_HandleExecutionInterrupt doesn't indicate that the +// execution should be aborted) is stored in AsmJSActivation::resumePC_. +// Unfortunately, loading this requires a scratch register which we don't have +// after restoring all registers. To hack around this, push the resumePC on the +// stack so that it can be popped directly into PC. static void GenerateOperationCallbackExit(ModuleCompiler &m, Label *throwLabel) { @@ -5516,7 +5520,7 @@ GenerateOperationCallbackExit(ModuleCompiler &m, Label *throwLabel) masm.push(Imm32(0)); // space for resumePC masm.pushFlags(); // after this we are safe to use sub masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below - masm.PushRegsInMask(AllRegs); // save all GP/FP registers + masm.PushRegsInMask(AllRegsExceptSP); // save all GP/FP registers (except SP) Register activation = ABIArgGenerator::NonArgReturnVolatileReg1; Register scratch = ABIArgGenerator::NonArgReturnVolatileReg2; @@ -5553,7 +5557,7 @@ GenerateOperationCallbackExit(ModuleCompiler &m, Label *throwLabel) masm.mov(ABIArgGenerator::NonVolatileReg, StackPointer); // Restore the machine state to before the interrupt. - masm.PopRegsInMask(AllRegs); // restore all GP/FP registers + masm.PopRegsInMask(AllRegsExceptSP); // restore all GP/FP registers (except SP) masm.popFlags(); // after this, nothing that sets conditions masm.ret(); // pop resumePC into PC #else