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

[masm][ia32][arm] Introduce helper to drop arguments.

This CL is a port of https://crrev.com/c/3045349 for ia32 and arm,
adding helper methods to drop arguments from the stack.

Drive-by: Add RootAsOperand to ia32.

Bug: v8:11112
Change-Id: I07b753d51b9fc9fc91bf09618b1315d146827123
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3069157Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76095}
parent a92f70d8
......@@ -129,9 +129,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
}
// Remove caller arguments from the stack and return.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
__ add(sp, sp, Operand(scratch, LSL, kPointerSizeLog2 - kSmiTagSize));
__ add(sp, sp, Operand(kPointerSize));
__ DropArguments(scratch, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ Jump(lr);
__ bind(&stack_overflow);
......@@ -276,9 +275,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::CONSTRUCT);
// Remove caller arguments from the stack and return.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
__ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
__ add(sp, sp, Operand(kPointerSize));
__ DropArguments(r1, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ Jump(lr);
__ bind(&check_receiver);
......@@ -828,7 +826,8 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
__ LeaveFrame(StackFrame::INTERPRETED);
// Drop receiver + arguments.
__ add(sp, sp, params_size, LeaveCC);
__ DropArguments(params_size, TurboAssembler::kCountIsBytes,
TurboAssembler::kCountIncludesReceiver);
}
// Tail-call |function_id| if |actual_marker| == |expected_marker|
......@@ -1862,8 +1861,8 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
__ ldr(r5, MemOperand(sp, kSystemPointerSize), ge); // thisArg
__ cmp(r0, Operand(2), ge);
__ ldr(r2, MemOperand(sp, 2 * kSystemPointerSize), ge); // argArray
__ add(sp, sp, Operand(r0, LSL, kSystemPointerSizeLog2));
__ str(r5, MemOperand(sp, 0));
__ DropArgumentsAndPushNewReceiver(r0, r5, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......@@ -1939,8 +1938,8 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
__ ldr(r5, MemOperand(sp, 2 * kSystemPointerSize), ge); // thisArgument
__ cmp(r0, Operand(3), ge);
__ ldr(r2, MemOperand(sp, 3 * kSystemPointerSize), ge); // argumentsList
__ add(sp, sp, Operand(r0, LSL, kSystemPointerSizeLog2));
__ str(r5, MemOperand(sp, 0));
__ DropArgumentsAndPushNewReceiver(r0, r5, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......@@ -1982,8 +1981,8 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ ldr(r2, MemOperand(sp, 2 * kSystemPointerSize), ge); // argumentsList
__ cmp(r0, Operand(3), ge);
__ ldr(r3, MemOperand(sp, 3 * kSystemPointerSize), ge); // new.target
__ add(sp, sp, Operand(r0, LSL, kSystemPointerSizeLog2));
__ str(r4, MemOperand(sp, 0)); // set undefined to the receiver
__ DropArgumentsAndPushNewReceiver(r0, r4, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......
......@@ -129,11 +129,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
}
// Remove caller arguments from the stack and return.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
__ PopReturnAddressTo(ecx);
__ lea(esp, Operand(esp, edx, times_half_system_pointer_size,
1 * kSystemPointerSize)); // 1 ~ receiver
__ PushReturnAddressFrom(ecx);
__ DropArguments(edx, ecx, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ ret(0);
__ bind(&stack_overflow);
......@@ -284,11 +281,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::CONSTRUCT);
// Remove caller arguments from the stack and return.
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
__ pop(ecx);
__ lea(esp, Operand(esp, edx, times_half_system_pointer_size,
1 * kSystemPointerSize)); // 1 ~ receiver
__ push(ecx);
__ DropArguments(edx, ecx, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ ret(0);
// Otherwise we do a smi check and fall through to check if the return value
......@@ -777,10 +771,8 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
__ leave();
// Drop receiver + arguments.
Register return_pc = scratch2;
__ PopReturnAddressTo(return_pc);
__ add(esp, params_size);
__ PushReturnAddressFrom(return_pc);
__ DropArguments(params_size, scratch2, TurboAssembler::kCountIsBytes,
TurboAssembler::kCountIncludesReceiver);
}
// Tail-call |function_id| if |actual_marker| == |expected_marker|
......@@ -1916,11 +1908,9 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
__ bind(&no_arg_array);
}
__ bind(&no_this_arg);
__ PopReturnAddressTo(ecx);
__ lea(esp,
Operand(esp, eax, times_system_pointer_size, kSystemPointerSize));
__ Push(edi);
__ PushReturnAddressFrom(ecx);
__ DropArgumentsAndPushNewReceiver(eax, edi, ecx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
// Restore receiver to edi.
__ movd(edi, xmm0);
......@@ -2027,11 +2017,9 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
// Spill argumentsList to use edx as a scratch register.
__ movd(xmm0, edx);
__ PopReturnAddressTo(edx);
__ lea(esp,
Operand(esp, eax, times_system_pointer_size, kSystemPointerSize));
__ Push(ecx);
__ PushReturnAddressFrom(edx);
__ DropArgumentsAndPushNewReceiver(eax, ecx, edx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
// Restore argumentsList.
__ movd(edx, xmm0);
......@@ -2087,11 +2075,10 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
// Spill argumentsList to use ecx as a scratch register.
__ movd(xmm0, ecx);
__ PopReturnAddressTo(ecx);
__ lea(esp,
Operand(esp, eax, times_system_pointer_size, kSystemPointerSize));
__ PushRoot(RootIndex::kUndefinedValue);
__ PushReturnAddressFrom(ecx);
__ DropArgumentsAndPushNewReceiver(
eax, masm->RootAsOperand(RootIndex::kUndefinedValue), ecx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
// Restore argumentsList.
__ movd(ecx, xmm0);
......
......@@ -129,7 +129,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
}
// Remove caller arguments from the stack and return.
__ DropArguments(rbx, rcx, MacroAssembler::kCountIsSmi);
__ DropArguments(rbx, rcx, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ ret(0);
......@@ -278,7 +279,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ movq(rbx, Operand(rbp, ConstructFrameConstants::kLengthOffset));
__ LeaveFrame(StackFrame::CONSTRUCT);
// Remove caller arguments from the stack and return.
__ DropArguments(rbx, rcx, MacroAssembler::kCountIsSmi);
__ DropArguments(rbx, rcx, TurboAssembler::kCountIsSmi,
TurboAssembler::kCountExcludesReceiver);
__ ret(0);
// If the result is a smi, it is *not* an object in the ECMA sense.
......@@ -874,8 +876,8 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
__ leave();
// Drop receiver + arguments.
__ DropArguments(params_size, scratch2, MacroAssembler::kCountIsBytes,
MacroAssembler::kCountIncludesReceiver);
__ DropArguments(params_size, scratch2, TurboAssembler::kCountIsBytes,
TurboAssembler::kCountIncludesReceiver);
}
// Tail-call |function_id| if |actual_marker| == |expected_marker|
......@@ -1891,7 +1893,9 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
__ bind(&no_arg_array);
}
__ bind(&no_this_arg);
__ DropArgumentsAndPushNewReceiver(rax, rdx, rcx);
__ DropArgumentsAndPushNewReceiver(rax, rdx, rcx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......@@ -1994,7 +1998,9 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
__ j(below, &done, Label::kNear);
__ movq(rbx, args[3]); // argumentsList
__ bind(&done);
__ DropArgumentsAndPushNewReceiver(rax, rdx, rcx);
__ DropArgumentsAndPushNewReceiver(rax, rdx, rcx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......@@ -2044,7 +2050,9 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ movq(rdx, args[3]); // new.target
__ bind(&done);
__ DropArgumentsAndPushNewReceiver(
rax, masm->RootAsOperand(RootIndex::kUndefinedValue), rcx);
rax, masm->RootAsOperand(RootIndex::kUndefinedValue), rcx,
TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
}
// ----------- S t a t e -------------
......@@ -3326,7 +3334,8 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// expected to be on the top of the stack).
// 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.
__ DropArguments(param_count, rbx);
__ DropArguments(param_count, rbx, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
__ ret(0);
// --------------------------------------------------------------------------
......
......@@ -1359,6 +1359,44 @@ void TurboAssembler::StubPrologue(StackFrame::Type type) {
void TurboAssembler::Prologue() { PushStandardFrame(r1); }
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode) {
int receiver_bytes = (mode == kCountExcludesReceiver) ? kPointerSize : 0;
switch (type) {
case kCountIsInteger: {
add(sp, sp, Operand(count, LSL, kPointerSizeLog2), LeaveCC);
break;
}
case kCountIsSmi: {
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
add(sp, sp, Operand(count, LSL, kPointerSizeLog2 - kSmiTagSize), LeaveCC);
break;
}
case kCountIsBytes: {
add(sp, sp, count, LeaveCC);
break;
}
}
if (receiver_bytes != 0) {
add(sp, sp, Operand(receiver_bytes), LeaveCC);
}
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode) {
DCHECK(!AreAliased(argc, receiver));
if (mode == kCountExcludesReceiver) {
// Drop arguments without receiver and override old receiver.
DropArguments(argc, type, kCountIncludesReceiver);
str(receiver, MemOperand(sp, 0));
} else {
DropArguments(argc, type, mode);
push(receiver);
}
}
void TurboAssembler::EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
ASM_CODE_COMMENT(this);
......
......@@ -76,6 +76,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void StubPrologue(StackFrame::Type type);
void Prologue();
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode);
// Push a standard frame, consisting of lr, fp, context and JS function
void PushStandardFrame(Register function_reg);
......
......@@ -81,11 +81,15 @@ void TurboAssembler::InitializeRootRegister() {
Move(kRootRegister, Immediate(isolate_root));
}
Operand TurboAssembler::RootAsOperand(RootIndex index) {
DCHECK(root_array_available());
return Operand(kRootRegister, RootRegisterOffsetForRootIndex(index));
}
void TurboAssembler::LoadRoot(Register destination, RootIndex index) {
ASM_CODE_COMMENT(this);
if (root_array_available()) {
mov(destination,
Operand(kRootRegister, RootRegisterOffsetForRootIndex(index)));
mov(destination, RootAsOperand(index));
return;
}
......@@ -123,7 +127,7 @@ void TurboAssembler::CompareRoot(Register with, Register scratch,
void TurboAssembler::CompareRoot(Register with, RootIndex index) {
ASM_CODE_COMMENT(this);
if (root_array_available()) {
cmp(with, Operand(kRootRegister, RootRegisterOffsetForRootIndex(index)));
cmp(with, RootAsOperand(index));
return;
}
......@@ -140,7 +144,7 @@ void MacroAssembler::PushRoot(RootIndex index) {
ASM_CODE_COMMENT(this);
if (root_array_available()) {
DCHECK(RootsTable::IsImmortalImmovable(index));
push(Operand(kRootRegister, RootRegisterOffsetForRootIndex(index)));
push(RootAsOperand(index));
return;
}
......@@ -234,7 +238,7 @@ Operand TurboAssembler::HeapObjectAsOperand(Handle<HeapObject> object) {
Builtin builtin;
RootIndex root_index;
if (isolate()->roots_table().IsRootHandle(object, &root_index)) {
return Operand(kRootRegister, RootRegisterOffsetForRootIndex(root_index));
return RootAsOperand(root_index);
} else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin)) {
return Operand(kRootRegister, RootRegisterOffsetForBuiltin(builtin));
} else if (object.is_identical_to(code_object_) &&
......@@ -1157,6 +1161,70 @@ void TurboAssembler::Prologue() {
push(kJavaScriptCallArgCountRegister); // Actual argument count.
}
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode) {
int receiver_bytes =
(mode == kCountExcludesReceiver) ? kSystemPointerSize : 0;
switch (type) {
case kCountIsInteger: {
lea(esp, Operand(esp, count, times_system_pointer_size, receiver_bytes));
break;
}
case kCountIsSmi: {
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
// SMIs are stored shifted left by 1 byte with the tag being 0.
// This is equivalent to multiplying by 2. To convert SMIs to bytes we
// can therefore just multiply the stored value by half the system pointer
// size.
lea(esp,
Operand(esp, count, times_half_system_pointer_size, receiver_bytes));
break;
}
case kCountIsBytes: {
if (receiver_bytes == 0) {
add(esp, count);
} else {
lea(esp, Operand(esp, count, times_1, receiver_bytes));
}
break;
}
}
}
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.is_reg(scratch));
PopReturnAddressTo(scratch);
DropArguments(argc, type, mode);
Push(receiver);
PushReturnAddressFrom(scratch);
}
void TurboAssembler::EnterFrame(StackFrame::Type type) {
ASM_CODE_COMMENT(this);
push(ebp);
......
......@@ -231,6 +231,20 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void StubPrologue(StackFrame::Type type);
void Prologue();
// Helpers for argument handling
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, Register scratch, ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Operand receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode);
void Lzcnt(Register dst, Register src) { Lzcnt(dst, Operand(src)); }
void Lzcnt(Register dst, Operand src);
......@@ -256,6 +270,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void InitializeRootRegister();
Operand RootAsOperand(RootIndex index);
void LoadRoot(Register destination, RootIndex index) final;
// Indirect root-relative loads.
......@@ -477,6 +492,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void ExceptionHandler() {}
// Define an exception handler and bind a label.
void BindExceptionHandler(Label* label) { bind(label); }
protected:
// 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.
......
......@@ -157,6 +157,7 @@ void MacroAssembler::PushAddress(ExternalReference source) {
}
Operand TurboAssembler::RootAsOperand(RootIndex index) {
DCHECK(root_array_available());
return Operand(kRootRegister, RootRegisterOffsetForRootIndex(index));
}
......@@ -1690,6 +1691,7 @@ void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
} else {
leaq(rsp, Operand(rsp, count, times_1, receiver_bytes));
}
break;
}
}
}
......
......@@ -513,17 +513,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
// 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);
void DropArguments(Register count, Register scratch, ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Operand receiver,
Register scratch,
ArgumentsCountType type,
ArgumentsCountMode mode);
// Calls Abort(msg) if the condition cc is not satisfied.
// Use --debug_code to enable.
......
......@@ -3949,15 +3949,18 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_slots).
__ add(argc_reg, argc_reg, Operand(1)); // Also pop the receiver.
// We must pop all arguments from the stack (including the receiver).
// The number of arguments without the receiver is
// max(argc_reg, parameter_slots-1), and the receiver is added in
// DropArguments().
DCHECK_EQ(0u, call_descriptor->CalleeSavedRegisters() & argc_reg.bit());
if (parameter_slots > 1) {
__ cmp(argc_reg, Operand(parameter_slots));
__ mov(argc_reg, Operand(parameter_slots), LeaveCC, lt);
const int parameter_slots_without_receiver = parameter_slots - 1;
__ cmp(argc_reg, Operand(parameter_slots_without_receiver));
__ mov(argc_reg, Operand(parameter_slots_without_receiver), LeaveCC, lt);
}
__ Drop(argc_reg);
__ DropArguments(argc_reg, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
} else if (additional_pop_count->IsImmediate()) {
DCHECK_EQ(Constant::kInt32, g.ToConstant(additional_pop_count).type());
int additional_count = g.ToConstant(additional_pop_count).ToInt32();
......
......@@ -4654,11 +4654,11 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_slots).
int parameter_slots_without_receiver =
parameter_slots - 1; // Exclude the receiver to simplify the
// computation. We'll account for it at the end.
// We must pop all arguments from the stack (including the receiver).
// The number of arguments without the receiver is
// max(argc_reg, parameter_slots-1), and the receiver is added in
// DropArguments().
int parameter_slots_without_receiver = parameter_slots - 1;
Label mismatch_return;
Register scratch_reg = edx;
DCHECK_NE(argc_reg, scratch_reg);
......@@ -4668,11 +4668,9 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
__ j(greater, &mismatch_return, Label::kNear);
__ Ret(parameter_slots * kSystemPointerSize, scratch_reg);
__ bind(&mismatch_return);
__ PopReturnAddressTo(scratch_reg);
__ lea(esp, Operand(esp, argc_reg, times_system_pointer_size,
kSystemPointerSize)); // Also pop the receiver.
__ DropArguments(argc_reg, scratch_reg, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
// We use a return instead of a jump for better return address prediction.
__ PushReturnAddressFrom(scratch_reg);
__ Ret();
} else if (additional_pop_count->IsImmediate()) {
int additional_count = g.ToConstant(additional_pop_count).ToInt32();
......
......@@ -4879,11 +4879,11 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_slots).
int parameter_slots_without_receiver =
parameter_slots - 1; // Exclude the receiver to simplify the
// computation. We'll account for it at the end.
// We must pop all arguments from the stack (including the receiver).
// The number of arguments without the receiver is
// max(argc_reg, parameter_slots-1), and the receiver is added in
// DropArguments().
int parameter_slots_without_receiver = parameter_slots - 1;
Label mismatch_return;
Register scratch_reg = r10;
DCHECK_NE(argc_reg, scratch_reg);
......@@ -4893,7 +4893,8 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
__ j(greater, &mismatch_return, Label::kNear);
__ Ret(parameter_slots * kSystemPointerSize, scratch_reg);
__ bind(&mismatch_return);
__ DropArguments(argc_reg, scratch_reg);
__ DropArguments(argc_reg, scratch_reg, TurboAssembler::kCountIsInteger,
TurboAssembler::kCountExcludesReceiver);
// We use a return instead of a jump for better return address prediction.
__ Ret();
} else if (additional_pop_count->IsImmediate()) {
......
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