Commit 1e8ab268 authored by Andreas Haas's avatar Andreas Haas Committed by V8 LUCI CQ

[win] Fix corner case in AllocateStackSpace

With this CL it is guaranteed that every time after AllocatedStackSpace
allocates a full page, this page also gets touched.

Background:

On Windows it is required to touch every new memory page on the stack
before adding another memory page. This is implemented in
{AllocateStackSpace}. This was implemented so far by repeatedly
allocating a new page, followed by touching the new page. The last
allocation, which may has up to the size of a page, did not get touched
anymore, with the assumption that allocated stack space will be used
before new stack space gets allocated. However, this assumption is
wrong. In Liftoff, the whole stack space that is needed for a function
gets allocated in the beginning of the function. This stack space may
only be used for spills though, and the spilling may only happen after
the first function call in the function. In this case the callee
function will write to its own stack frame before the stack frame of the
caller gets used.

As written above, the last allocation does not get touched anymore. In
the case that this is a full memory page, this can mean that a full
memory page gets skipped without getting touched. With this CL it is
guaranteed that the last allocation is always smaller than one page, and
therefore it is impossible to skip a full page without touching it as
long as there are no two calls to {AllocateStackSpace} without a {push}
in between.


Bug: v8:12063
Change-Id: If0bb41212e882beb926aac538001b02f179fc03e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3168276
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76915}
parent b88bfa9f
......@@ -956,7 +956,7 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
bind(&check_offset);
cmp(bytes_scratch, kStackPageSize);
j(greater, &touch_next_page);
j(greater_equal, &touch_next_page);
sub(esp, bytes_scratch);
}
......@@ -964,7 +964,7 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
void TurboAssembler::AllocateStackSpace(int bytes) {
ASM_CODE_COMMENT(this);
DCHECK_GE(bytes, 0);
while (bytes > kStackPageSize) {
while (bytes >= kStackPageSize) {
sub(esp, Immediate(kStackPageSize));
mov(Operand(esp, 0), Immediate(0));
bytes -= kStackPageSize;
......
......@@ -2791,7 +2791,7 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
bind(&check_offset);
cmpq(bytes_scratch, Immediate(kStackPageSize));
j(greater, &touch_next_page);
j(greater_equal, &touch_next_page);
subq(rsp, bytes_scratch);
}
......@@ -2799,7 +2799,7 @@ void TurboAssembler::AllocateStackSpace(Register bytes_scratch) {
void TurboAssembler::AllocateStackSpace(int bytes) {
ASM_CODE_COMMENT(this);
DCHECK_GE(bytes, 0);
while (bytes > kStackPageSize) {
while (bytes >= kStackPageSize) {
subq(rsp, Immediate(kStackPageSize));
movb(Operand(rsp, 0), Immediate(0));
bytes -= kStackPageSize;
......
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