Commit 79349d50 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[ia32] Move explicit stack limit checking to TurboAssembler

Liftoff needs to emit the same code, thus move it to a place where it
can be reused.
Also, switch the _MSC_VER switch to V8_OS_WIN. It is unclear if
_MSC_VER would also be set in clang. V8_OS_WIN seems to fit better.

Drive-by: Reorder the code to save one jmp in the loop (loop inversion).

R=mstarzinger@chromium.org

Bug: v8:7908, v8:6600
Change-Id: Ia76aa4dad3f96e179a9daad8c1551b1aab499878
Reviewed-on: https://chromium-review.googlesource.com/1120174
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54113}
parent 4c9919e5
......@@ -1033,30 +1033,11 @@ void Generate_InterpreterPushZeroAndArgsAndReturnAddress(
Generate_StackOverflowCheck(masm, num_args, scratch1, scratch2,
stack_overflow, true);
// Step 1 - Update the stack pointer. scratch1 already contains the required
// increment to the stack. i.e. num_args + 1 stack slots. This is computed in
// the Generate_StackOverflowCheck.
#ifdef _MSC_VER
// TODO(mythria): Move it to macro assembler.
// In windows, we cannot increment the stack size by more than one page
// (mimimum page size is 4KB) without accessing at least one byte on the
// page. Check this:
// https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
const int page_size = 4 * 1024;
Label check_offset, update_stack_pointer;
__ bind(&check_offset);
__ cmp(scratch1, page_size);
__ j(less, &update_stack_pointer);
__ sub(esp, Immediate(page_size));
// Just to touch the page, before we increment further.
__ mov(Operand(esp, 0), Immediate(0));
__ sub(scratch1, Immediate(page_size));
__ jmp(&check_offset);
__ bind(&update_stack_pointer);
#endif
__ sub(esp, scratch1);
// Step 1 - Update the stack pointer. scratch1 already contains the required
// increment to the stack. i.e. num_args + 1 stack slots. This is computed in
// Generate_StackOverflowCheck.
__ AllocateStackFrame(scratch1);
// Step 2 move return_address and slots above it to the correct locations.
// Move from top to bottom, otherwise we may overwrite when num_args = 0 or 1,
......
......@@ -625,6 +625,30 @@ void TurboAssembler::LeaveFrame(StackFrame::Type type) {
leave();
}
#ifdef V8_OS_WIN
void TurboAssembler::AllocateStackFrame(Register bytes_scratch) {
// In windows, we cannot increment the stack size by more than one page
// (minimum page size is 4KB) without accessing at least one byte on the
// page. Check this:
// https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
constexpr int kPageSize = 4 * 1024;
Label check_offset;
Label touch_next_page;
jmp(&check_offset);
bind(&touch_next_page);
sub(esp, Immediate(kPageSize));
// Just to touch the page, before we increment further.
mov(Operand(esp, 0), Immediate(0));
sub(bytes_scratch, Immediate(kPageSize));
bind(&check_offset);
cmp(bytes_scratch, kPageSize);
j(greater, &touch_next_page);
sub(esp, bytes_scratch);
}
#endif
void MacroAssembler::EnterBuiltinFrame(Register context, Register target,
Register argc) {
Push(ebp);
......
......@@ -73,6 +73,19 @@ class TurboAssembler : public TurboAssemblerBase {
}
void LeaveFrame(StackFrame::Type type);
// Allocate a stack frame of given size (i.e. decrement {esp} by the value
// stored in the given register).
#ifdef V8_OS_WIN
// On win32, take special care if the number of bytes is greater than 4096:
// Ensure that each page within the new stack frame is touched once in
// decreasing order. See
// https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
// Use {bytes_scratch} as scratch register for this procedure.
void AllocateStackFrame(Register bytes_scratch);
#else
void AllocateStackFrame(Register bytes) { sub(esp, bytes); }
#endif
// Print a message to stdout and abort execution.
void Abort(AbortReason reason);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment