Commit 6bd44dfe authored by Patrick Thier's avatar Patrick Thier Committed by V8 LUCI CQ

[masm][x64] Introduce Helper to drop arguments.

- Add DropArguments() to x64 TurboAssembler to get rid of arguments on
the stack while preserving the return address.
- Add DropArgumentsAndPushNewReceiver() to x64 TurboAssembler to get rid
of arguments on the stack and push a new receiver, while preserving
the return address.

Bug: v8:11112
Change-Id: I39ea012219ae3748a73933188eb860ce794de2f1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3045349
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75859}
parent d70ee61c
...@@ -129,10 +129,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -129,10 +129,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
} }
// Remove caller arguments from the stack and return. // Remove caller arguments from the stack and return.
__ PopReturnAddressTo(rcx); __ DropArguments(rbx, rcx, MacroAssembler::kCountIsSmi);
SmiIndex index = masm->SmiToIndex(rbx, rbx, kSystemPointerSizeLog2);
__ leaq(rsp, Operand(rsp, index.reg, index.scale, 1 * kSystemPointerSize));
__ PushReturnAddressFrom(rcx);
__ ret(0); __ ret(0);
...@@ -281,10 +278,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -281,10 +278,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ movq(rbx, Operand(rbp, ConstructFrameConstants::kLengthOffset)); __ movq(rbx, Operand(rbp, ConstructFrameConstants::kLengthOffset));
__ LeaveFrame(StackFrame::CONSTRUCT); __ LeaveFrame(StackFrame::CONSTRUCT);
// Remove caller arguments from the stack and return. // Remove caller arguments from the stack and return.
__ PopReturnAddressTo(rcx); __ DropArguments(rbx, rcx, MacroAssembler::kCountIsSmi);
SmiIndex index = masm->SmiToIndex(rbx, rbx, kSystemPointerSizeLog2);
__ leaq(rsp, Operand(rsp, index.reg, index.scale, 1 * kSystemPointerSize));
__ PushReturnAddressFrom(rcx);
__ ret(0); __ ret(0);
// If the result is a smi, it is *not* an object in the ECMA sense. // If the result is a smi, it is *not* an object in the ECMA sense.
...@@ -880,10 +874,8 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, ...@@ -880,10 +874,8 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
__ leave(); __ leave();
// Drop receiver + arguments. // Drop receiver + arguments.
Register return_pc = scratch2; __ DropArguments(params_size, scratch2, MacroAssembler::kCountIsBytes,
__ PopReturnAddressTo(return_pc); MacroAssembler::kCountIncludesReceiver);
__ addq(rsp, params_size);
__ PushReturnAddressFrom(return_pc);
} }
// Tail-call |function_id| if |actual_marker| == |expected_marker| // Tail-call |function_id| if |actual_marker| == |expected_marker|
...@@ -1899,11 +1891,7 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { ...@@ -1899,11 +1891,7 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
__ bind(&no_arg_array); __ bind(&no_arg_array);
} }
__ bind(&no_this_arg); __ bind(&no_this_arg);
__ PopReturnAddressTo(rcx); __ DropArgumentsAndPushNewReceiver(rax, rdx, rcx);
__ leaq(rsp,
Operand(rsp, rax, times_system_pointer_size, kSystemPointerSize));
__ Push(rdx);
__ PushReturnAddressFrom(rcx);
} }
// ----------- S t a t e ------------- // ----------- S t a t e -------------
...@@ -2006,11 +1994,7 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) { ...@@ -2006,11 +1994,7 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
__ j(below, &done, Label::kNear); __ j(below, &done, Label::kNear);
__ movq(rbx, args[3]); // argumentsList __ movq(rbx, args[3]); // argumentsList
__ bind(&done); __ bind(&done);
__ PopReturnAddressTo(rcx); __ DropArgumentsAndPushNewReceiver(rax, rdx, rcx);
__ leaq(rsp,
Operand(rsp, rax, times_system_pointer_size, kSystemPointerSize));
__ Push(rdx);
__ PushReturnAddressFrom(rcx);
} }
// ----------- S t a t e ------------- // ----------- S t a t e -------------
...@@ -2059,11 +2043,8 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { ...@@ -2059,11 +2043,8 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ j(below, &done, Label::kNear); __ j(below, &done, Label::kNear);
__ movq(rdx, args[3]); // new.target __ movq(rdx, args[3]); // new.target
__ bind(&done); __ bind(&done);
__ PopReturnAddressTo(rcx); __ DropArgumentsAndPushNewReceiver(
__ leaq(rsp, rax, masm->RootAsOperand(RootIndex::kUndefinedValue), rcx);
Operand(rsp, rax, times_system_pointer_size, kSystemPointerSize));
__ PushRoot(RootIndex::kUndefinedValue);
__ PushReturnAddressFrom(rcx);
} }
// ----------- S t a t e ------------- // ----------- S t a t e -------------
...@@ -3345,16 +3326,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3345,16 +3326,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// expected to be on the top of the stack). // expected to be on the top of the stack).
// We cannot use just the ret instruction for this, because we cannot pass the // We cannot use just the ret instruction for this, because we cannot pass the
// number of slots to remove in a Register as an argument. // number of slots to remove in a Register as an argument.
Register return_addr = rbx; __ DropArguments(param_count, rbx);
__ popq(return_addr);
Register caller_frame_slots_count = param_count;
// Add one to also pop the receiver. The receiver is passed to a JSFunction
// over the stack but is neither included in the number of parameters passed
// to this function nor in the number of parameters expected in this function.
__ addq(caller_frame_slots_count, Immediate(1));
__ shlq(caller_frame_slots_count, Immediate(kSystemPointerSizeLog2));
__ addq(rsp, caller_frame_slots_count);
__ pushq(return_addr);
__ ret(0); __ ret(0);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
...@@ -1669,6 +1669,64 @@ void MacroAssembler::DropUnderReturnAddress(int stack_elements, ...@@ -1669,6 +1669,64 @@ void MacroAssembler::DropUnderReturnAddress(int stack_elements,
PushReturnAddressFrom(scratch); PushReturnAddressFrom(scratch);
} }
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode) {
int receiver_bytes =
(mode == kCountExcludesReceiver) ? kSystemPointerSize : 0;
switch (type) {
case kCountIsInteger: {
leaq(rsp, Operand(rsp, count, times_system_pointer_size, receiver_bytes));
break;
}
case kCountIsSmi: {
SmiIndex index = SmiToIndex(count, count, kSystemPointerSizeLog2);
leaq(rsp, Operand(rsp, index.reg, index.scale, receiver_bytes));
break;
}
case kCountIsBytes: {
if (receiver_bytes == 0) {
addq(rsp, count);
} else {
leaq(rsp, Operand(rsp, count, times_1, receiver_bytes));
}
}
}
}
void TurboAssembler::DropArguments(Register count, Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode) {
DCHECK(!AreAliased(count, scratch));
PopReturnAddressTo(scratch);
DropArguments(count, type, mode);
PushReturnAddressFrom(scratch);
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode) {
DCHECK(!AreAliased(argc, receiver, scratch));
PopReturnAddressTo(scratch);
DropArguments(argc, type, mode);
Push(receiver);
PushReturnAddressFrom(scratch);
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Operand receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode) {
DCHECK(!AreAliased(argc, scratch));
DCHECK(!receiver.AddressUsesRegister(scratch));
PopReturnAddressTo(scratch);
DropArguments(argc, type, mode);
Push(receiver);
PushReturnAddressFrom(scratch);
}
void TurboAssembler::Push(Register src) { pushq(src); } void TurboAssembler::Push(Register src) { pushq(src); }
void TurboAssembler::Push(Operand src) { pushq(src); } void TurboAssembler::Push(Operand src) { pushq(src); }
......
...@@ -510,6 +510,21 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler { ...@@ -510,6 +510,21 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void StubPrologue(StackFrame::Type type); void StubPrologue(StackFrame::Type type);
void Prologue(); void Prologue();
// Helpers for argument handling
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, Register scratch,
ArgumentsCountType type = kCountIsInteger,
ArgumentsCountMode mode = kCountExcludesReceiver);
void DropArgumentsAndPushNewReceiver(
Register argc, Register receiver, Register scratch,
ArgumentsCountType type = kCountIsInteger,
ArgumentsCountMode mode = kCountExcludesReceiver);
void DropArgumentsAndPushNewReceiver(
Register argc, Operand receiver, Register scratch,
ArgumentsCountType type = kCountIsInteger,
ArgumentsCountMode mode = kCountExcludesReceiver);
// Calls Abort(msg) if the condition cc is not satisfied. // Calls Abort(msg) if the condition cc is not satisfied.
// Use --debug_code to enable. // Use --debug_code to enable.
void Assert(Condition cc, AbortReason reason); void Assert(Condition cc, AbortReason reason);
...@@ -694,6 +709,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler { ...@@ -694,6 +709,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
// Returns a register holding the smi value. The register MUST NOT be // Returns a register holding the smi value. The register MUST NOT be
// modified. It may be the "smi 1 constant" register. // modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi value); Register GetSmiConstant(Smi value);
// Drops arguments assuming that the return address was already popped.
void DropArguments(Register count, ArgumentsCountType type = kCountIsInteger,
ArgumentsCountMode mode = kCountExcludesReceiver);
}; };
// MacroAssembler implements a collection of frequently used macros. // MacroAssembler implements a collection of frequently used macros.
......
...@@ -4891,11 +4891,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) { ...@@ -4891,11 +4891,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
__ j(greater, &mismatch_return, Label::kNear); __ j(greater, &mismatch_return, Label::kNear);
__ Ret(parameter_slots * kSystemPointerSize, scratch_reg); __ Ret(parameter_slots * kSystemPointerSize, scratch_reg);
__ bind(&mismatch_return); __ bind(&mismatch_return);
__ PopReturnAddressTo(scratch_reg); __ DropArguments(argc_reg, scratch_reg);
__ leaq(rsp, Operand(rsp, argc_reg, times_system_pointer_size,
kSystemPointerSize)); // Also pop the receiver.
// We use a return instead of a jump for better return address prediction. // We use a return instead of a jump for better return address prediction.
__ PushReturnAddressFrom(scratch_reg);
__ Ret(); __ Ret();
} else if (additional_pop_count->IsImmediate()) { } else if (additional_pop_count->IsImmediate()) {
Register scratch_reg = r10; Register scratch_reg = r10;
......
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