Bug 1488763 - Unify stack touch logic across all platforms r=jandem

This incidentally also -adds- the stack touch logic to ARM64.

Differential Revision: https://phabricator.services.mozilla.com/D10395

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matthew Gaudet 2018-11-05 09:35:01 +00:00
parent 8c500290c1
commit 42e2aee566
7 changed files with 36 additions and 67 deletions

View File

@ -621,12 +621,6 @@ class JitRealm
void InvalidateAll(FreeOp* fop, JS::Zone* zone);
void FinishInvalidation(FreeOp* fop, JSScript* script);
// On windows systems, really large frames need to be incrementally touched.
// The following constant defines the minimum increment of the touch.
#ifdef XP_WIN
const unsigned WINDOWS_BIG_FRAME_TOUCH_INCREMENT = 4096 - 1;
#endif
// This class ensures JIT code is executable on its destruction. Creators
// must call makeWritable(), and not attempt to write to the buffer if it fails.
//

View File

@ -3965,6 +3965,35 @@ MacroAssembler::performPendingReadBarriers()
}
}
// Can't push large frames blindly on windows, so we must touch frame memory
// incrementally, with no more than 4096 - 1 bytes between touches.
//
// This is used across all platforms for simplicity.
void
MacroAssembler::touchFrameValues(Register numStackValues, Register scratch1, Register scratch2)
{
const size_t FRAME_TOUCH_INCREMENT = 2048;
static_assert(FRAME_TOUCH_INCREMENT < 4096 -1, "Frame increment is too large");
moveStackPtrTo(scratch2);
mov(numStackValues, scratch1);
lshiftPtr(Imm32(3), scratch1);
subPtr(scratch1, scratch2);
{
moveStackPtrTo(scratch1);
subPtr(Imm32(FRAME_TOUCH_INCREMENT), scratch1);
Label touchFrameLoop;
Label touchFrameLoopEnd;
bind(&touchFrameLoop);
branchPtr(Assembler::Below, scratch1, scratch2, &touchFrameLoopEnd);
store32(Imm32(0), Address(scratch1, 0));
subPtr(Imm32(FRAME_TOUCH_INCREMENT), scratch1);
jump(&touchFrameLoop);
bind(&touchFrameLoopEnd);
}
}
namespace js {
namespace jit {

View File

@ -2771,6 +2771,8 @@ class MacroAssembler : public MacroAssemblerSpecific
void performPendingReadBarriers();
void touchFrameValues(Register numStackValues, Register scratch1, Register scratch2);
private:
// Methods to get a singleton object or object group from a type set without
// a read barrier, and record the result so that we can perform the barrier

View File

@ -255,29 +255,9 @@ JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm)
// Reserve frame.
Register framePtr = r11;
masm.subPtr(Imm32(BaselineFrame::Size()), sp);
masm.mov(sp, framePtr);
#ifdef XP_WIN
// Can't push large frames blindly on windows. Touch frame memory
// incrementally.
masm.ma_lsl(Imm32(3), numStackValues, scratch);
masm.subPtr(scratch, framePtr);
{
ScratchRegisterScope asmScratch(masm);
masm.ma_sub(sp, Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch, asmScratch);
}
{
Label touchFrameLoop;
Label touchFrameLoopEnd;
masm.bind(&touchFrameLoop);
masm.branchPtr(Assembler::Below, scratch, framePtr, &touchFrameLoopEnd);
masm.store32(Imm32(0), Address(scratch, 0));
masm.subPtr(Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch);
masm.jump(&touchFrameLoop);
masm.bind(&touchFrameLoopEnd);
}
masm.touchFrameValues(numStackValues, scratch, framePtr);
masm.mov(sp, framePtr);
#endif
// Reserve space for locals and stack values.
masm.ma_lsl(Imm32(3), numStackValues, scratch);

View File

@ -173,6 +173,8 @@ JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm)
// Reserve frame.
masm.subFromStackPtr(Imm32(BaselineFrame::Size()));
masm.touchFrameValues(reg_osrNStack, ScratchReg2, BaselineFrameReg);
masm.moveStackPtrTo(BaselineFrameReg);
// Reserve space for locals and stack values.

View File

@ -197,28 +197,9 @@ JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm)
// Reserve frame.
Register framePtr = rbp;
masm.subPtr(Imm32(BaselineFrame::Size()), rsp);
masm.mov(rsp, framePtr);
#ifdef XP_WIN
// Can't push large frames blindly on windows. Touch frame memory incrementally.
masm.mov(numStackValues, scratch);
masm.lshiftPtr(Imm32(3), scratch);
masm.subPtr(scratch, framePtr);
{
masm.movePtr(rsp, scratch);
masm.subPtr(Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch);
Label touchFrameLoop;
Label touchFrameLoopEnd;
masm.bind(&touchFrameLoop);
masm.branchPtr(Assembler::Below, scratch, framePtr, &touchFrameLoopEnd);
masm.store32(Imm32(0), Address(scratch, 0));
masm.subPtr(Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch);
masm.jump(&touchFrameLoop);
masm.bind(&touchFrameLoopEnd);
}
masm.touchFrameValues(numStackValues, scratch, framePtr);
masm.mov(rsp, framePtr);
#endif
// Reserve space for locals and stack values.
Register valuesSize = regs.takeAny();

View File

@ -191,28 +191,9 @@ JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm)
// Reserve frame.
Register framePtr = ebp;
masm.subPtr(Imm32(BaselineFrame::Size()), esp);
masm.mov(esp, framePtr);
#ifdef XP_WIN
// Can't push large frames blindly on windows. Touch frame memory incrementally.
masm.mov(numStackValues, scratch);
masm.shll(Imm32(3), scratch);
masm.subPtr(scratch, framePtr);
{
masm.movePtr(esp, scratch);
masm.subPtr(Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch);
Label touchFrameLoop;
Label touchFrameLoopEnd;
masm.bind(&touchFrameLoop);
masm.branchPtr(Assembler::Below, scratch, framePtr, &touchFrameLoopEnd);
masm.store32(Imm32(0), Address(scratch, 0));
masm.subPtr(Imm32(WINDOWS_BIG_FRAME_TOUCH_INCREMENT), scratch);
masm.jump(&touchFrameLoop);
masm.bind(&touchFrameLoopEnd);
}
masm.touchFrameValues(numStackValues, scratch, framePtr);
masm.mov(esp, framePtr);
#endif
// Reserve space for locals and stack values.
masm.mov(numStackValues, scratch);