Commit 4fd61de7 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Fix over application return stack cleanup

Under over-application (passing more arguments into a function than its
formal parameter count), we need to use the passed argc to clean up the
stack, rather than the formal parameter count. Fix Maglev's Return node
code to do the appropriate check and dynamic sized return.

Bug: v8:7700
Change-Id: I36037d29e14323b336974d4b75b75f5702ce8a28
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3555767Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79649}
parent 9641ce64
...@@ -772,9 +772,35 @@ void Return::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -772,9 +772,35 @@ void Return::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
DCHECK_EQ(ToRegister(value_input()), kReturnRegister0); DCHECK_EQ(ToRegister(value_input()), kReturnRegister0);
// We're not going to continue execution, so we can use an arbitrary register
// here instead of relying on temporaries from the register allocator.
Register actual_params_size = r8;
// Compute the size of the actual parameters + receiver (in bytes).
// TODO(leszeks): Consider making this an input into Return to re-use the
// incoming argc's register (if it's still valid).
__ movq(actual_params_size,
MemOperand(rbp, StandardFrameConstants::kArgCOffset));
// Leave the frame.
// TODO(leszeks): Add a new frame maker for Maglev.
__ LeaveFrame(StackFrame::BASELINE); __ LeaveFrame(StackFrame::BASELINE);
// If actual is bigger than formal, then we should use it to free up the stack
// arguments.
Label drop_dynamic_arg_size;
__ cmpq(actual_params_size, Immediate(code_gen_state->parameter_count()));
__ j(greater, &drop_dynamic_arg_size);
// Drop receiver + arguments according to static formal arguments size.
__ Ret(code_gen_state->parameter_count() * kSystemPointerSize, __ Ret(code_gen_state->parameter_count() * kSystemPointerSize,
kScratchRegister); kScratchRegister);
__ bind(&drop_dynamic_arg_size);
// Drop receiver + arguments according to dynamic arguments size.
__ DropArguments(actual_params_size, r9, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountIncludesReceiver);
__ Ret();
} }
void Jump::AllocateVreg(MaglevVregAllocationState* vreg_state, void Jump::AllocateVreg(MaglevVregAllocationState* vreg_state,
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --maglev --allow-natives-syntax
function f(x) {
return x;
}
%PrepareFunctionForOptimization(f);
// f(x) takes one argument but we are under-applying here
assertEquals(undefined, f());
// f(x) takes one argument but we are over-applying here
assertEquals(1, f(1, 2));
%OptimizeMaglevOnNextCall(f);
// f(x) takes one argument but we are under-applying here
assertEquals(undefined, f());
// f(x) takes one argument but we are over-applying here
assertEquals(1, f(1, 2));
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