[codegen][x64] Simplify stack overflow check

We can avoid the scratch register by directly using the operand in the
"sub" instruction.

R=victorgomes@chromium.org

Bug: v8:12017
Change-Id: Ib1768a92b0ef98bf7dbed522f467eff395d08e8d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3069138
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76082}
This commit is contained in:
Clemens Backes 2021-08-03 15:42:57 +02:00 committed by V8 LUCI CQ
parent 9470b2770e
commit 3cf7b9ca41
3 changed files with 19 additions and 20 deletions

View File

@ -92,7 +92,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// -----------------------------------
Label stack_overflow;
__ StackOverflowCheck(rax, rcx, &stack_overflow, Label::kFar);
__ StackOverflowCheck(rax, &stack_overflow, Label::kFar);
// Enter a construct frame.
{
@ -225,9 +225,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ SmiUntag(rax, Operand(rbp, ConstructFrameConstants::kLengthOffset));
// Check if we have enough stack space to push all arguments.
// Argument count in rax. Clobbers rcx.
// Argument count in rax.
Label stack_overflow;
__ StackOverflowCheck(rax, rcx, &stack_overflow);
__ StackOverflowCheck(rax, &stack_overflow);
// TODO(victorgomes): When the arguments adaptor is completely removed, we
// should get the formal parameter count and copy the arguments in its
@ -593,9 +593,9 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// r9 : receiver
// Check if we have enough stack space to push all arguments.
// Argument count in rax. Clobbers rcx.
// Argument count in rax.
Label enough_stack_space, stack_overflow;
__ StackOverflowCheck(rax, rcx, &stack_overflow, Label::kNear);
__ StackOverflowCheck(rax, &stack_overflow, Label::kNear);
__ jmp(&enough_stack_space, Label::kNear);
__ bind(&stack_overflow);
@ -1388,7 +1388,7 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
__ leal(rcx, Operand(rax, 1)); // Add one for receiver.
// Add a stack check before pushing arguments.
__ StackOverflowCheck(rcx, rdx, &stack_overflow);
__ StackOverflowCheck(rcx, &stack_overflow);
// Pop return address to allow tail-call after pushing arguments.
__ PopReturnAddressTo(kScratchRegister);
@ -1449,7 +1449,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
Label stack_overflow;
// Add a stack check before pushing arguments.
__ StackOverflowCheck(rax, r8, &stack_overflow);
__ StackOverflowCheck(rax, &stack_overflow);
// Pop return address to allow tail-call after pushing arguments.
__ PopReturnAddressTo(kScratchRegister);
@ -2101,7 +2101,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
}
Label stack_overflow;
__ StackOverflowCheck(rcx, r8, &stack_overflow, Label::kNear);
__ StackOverflowCheck(rcx, &stack_overflow, Label::kNear);
// Push additional arguments onto the stack.
// Move the arguments already in the stack,
@ -2203,7 +2203,7 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
// -----------------------------------
// Check for stack overflow.
__ StackOverflowCheck(r8, r12, &stack_overflow, Label::kNear);
__ StackOverflowCheck(r8, &stack_overflow, Label::kNear);
// Forward the arguments from the caller frame.
// Move the arguments already in the stack,

View File

@ -3012,23 +3012,22 @@ Operand MacroAssembler::StackLimitAsOperand(StackLimitKind kind) {
}
void MacroAssembler::StackOverflowCheck(
Register num_args, Register scratch, Label* stack_overflow,
Register num_args, Label* stack_overflow,
Label::Distance stack_overflow_distance) {
ASM_CODE_COMMENT(this);
DCHECK_NE(num_args, scratch);
DCHECK_NE(num_args, kScratchRegister);
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
movq(kScratchRegister, StackLimitAsOperand(StackLimitKind::kRealStackLimit));
movq(scratch, rsp);
// Make scratch the space we have left. The stack might already be overflowed
// here which will cause scratch to become negative.
subq(scratch, kScratchRegister);
movq(kScratchRegister, rsp);
// Make kScratchRegister the space we have left. The stack might already be
// overflowed here which will cause kScratchRegister to become negative.
subq(kScratchRegister, StackLimitAsOperand(StackLimitKind::kRealStackLimit));
// TODO(victorgomes): Use ia32 approach with leaq, since it requires less
// instructions.
sarq(scratch, Immediate(kSystemPointerSizeLog2));
sarq(kScratchRegister, Immediate(kSystemPointerSizeLog2));
// Check if the arguments will overflow the stack.
cmpq(scratch, num_args);
cmpq(kScratchRegister, num_args);
// Signed comparison.
// TODO(victorgomes): Save some bytes in the builtins that use stack checks
// by jumping to a builtin that throws the exception.
@ -3055,7 +3054,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
j(less_equal, &regular_invoke, Label::kFar);
Label stack_overflow;
StackOverflowCheck(expected_parameter_count, rcx, &stack_overflow);
StackOverflowCheck(expected_parameter_count, &stack_overflow);
// Underapplication. Move the arguments already in the stack, including the
// receiver and the return address.

View File

@ -968,7 +968,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Stack limit utilities
Operand StackLimitAsOperand(StackLimitKind kind);
void StackOverflowCheck(
Register num_args, Register scratch, Label* stack_overflow,
Register num_args, Label* stack_overflow,
Label::Distance stack_overflow_distance = Label::kFar);
// ---------------------------------------------------------------------------