Commit 4adc7c7f authored by Liu yu's avatar Liu yu Committed by Commit Bot

Revert "[mips] Remove arguments adaptor frame"

This reverts commit 7257dc93.

Reason for revert:
- New test fail on mips64el: https://logs.chromium.org/logs/v8/buildbucket/cr-buildbucket.appspot.com/8864502401132417824/+/steps/Check/0/logs/modules-import-large/0

Original change's description:
> [mips] Remove arguments adaptor frame
>
> Port: 958d8e9f
>
> Bug: v8:10201
>
> Change-Id: I27d29f2a1f1d5f659d558b5fd776b88474d9b140
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2513867
> Auto-Submit: Liu yu <liuyu@loongson.cn>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70964}

TBR=jgruber@chromium.org,liuyu@loongson.cn

Change-Id: Iddca9684995409fb9a1f3340b3a1931b1b5b472b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:10201
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2519189Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70980}
parent 8ca481ed
......@@ -112,7 +112,6 @@ declare_args() {
# Disable arguments adaptor frame (sets -dV8_NO_ARGUMENTS_ADAPTOR).
v8_disable_arguments_adaptor =
v8_current_cpu == "x86" || v8_current_cpu == "x64" ||
v8_current_cpu == "mipsel" || v8_current_cpu == "mips64el" ||
v8_current_cpu == "arm"
# Sets -dOBJECT_PRINT.
......
This diff is collapsed.
This diff is collapsed.
......@@ -4387,106 +4387,23 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
mov(sp, dst_reg);
}
void MacroAssembler::LoadStackLimit(Register destination, StackLimitKind kind) {
DCHECK(root_array_available());
Isolate* isolate = this->isolate();
ExternalReference limit =
kind == StackLimitKind::kRealStackLimit
? ExternalReference::address_of_real_jslimit(isolate)
: ExternalReference::address_of_jslimit(isolate);
DCHECK(TurboAssembler::IsAddressableThroughRootRegister(isolate, limit));
intptr_t offset =
TurboAssembler::RootRegisterOffsetForExternalReference(isolate, limit);
CHECK(is_int32(offset));
Lw(destination, MemOperand(kRootRegister, static_cast<int32_t>(offset)));
}
void MacroAssembler::StackOverflowCheck(Register num_args, Register scratch1,
Register scratch2,
Label* stack_overflow) {
// 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.
LoadStackLimit(scratch1, StackLimitKind::kRealStackLimit);
// Make scratch1 the space we have left. The stack might already be overflowed
// here which will cause scratch1 to become negative.
subu(scratch1, sp, scratch1);
// Check if the arguments will overflow the stack.
sll(scratch2, num_args, kPointerSizeLog2);
// Signed comparison.
Branch(stack_overflow, le, scratch1, Operand(scratch2));
}
void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Register actual_parameter_count,
Label* done, InvokeFlag flag) {
Label regular_invoke;
// Check whether the expected and actual arguments count match. The
// registers are set up according to contract with
// ArgumentsAdaptorTrampoline:
// a0: actual arguments count
// a1: function (passed through to callee)
// a2: expected arguments count
// The code below is made a lot easier because the calling code already sets
// up actual and expected registers according to the contract.
DCHECK_EQ(actual_parameter_count, a0);
DCHECK_EQ(expected_parameter_count, a2);
#ifdef V8_NO_ARGUMENTS_ADAPTOR
// If the expected parameter count is equal to the adaptor sentinel, no need
// to push undefined value as arguments.
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
// If overapplication or if the actual argument count is equal to the
// formal parameter count, no need to push extra undefined values.
Subu(expected_parameter_count, expected_parameter_count,
actual_parameter_count);
Branch(&regular_invoke, le, expected_parameter_count, Operand(zero_reg));
Label stack_overflow;
StackOverflowCheck(expected_parameter_count, t0, t1, &stack_overflow);
// Underapplication. Move the arguments already in the stack, including the
// receiver and the return address.
{
Label copy;
Register src = t3, dest = t4;
mov(src, sp);
sll(t0, expected_parameter_count, kSystemPointerSizeLog2);
Subu(sp, sp, Operand(t0));
// Update stack pointer.
mov(dest, sp);
mov(t0, a0);
bind(&copy);
Lw(t1, MemOperand(src, 0));
Sw(t1, MemOperand(dest, 0));
Subu(t0, t0, Operand(1));
Addu(src, src, Operand(kSystemPointerSize));
Addu(dest, dest, Operand(kSystemPointerSize));
Branch(&copy, ge, t0, Operand(zero_reg));
}
// Fill remaining expected arguments with undefined values.
LoadRoot(t0, RootIndex::kUndefinedValue);
{
Label loop;
bind(&loop);
Sw(t0, MemOperand(t4, 0));
Subu(expected_parameter_count, expected_parameter_count, Operand(1));
Addu(t4, t4, Operand(kSystemPointerSize));
Branch(&loop, gt, expected_parameter_count, Operand(zero_reg));
}
b(&regular_invoke);
nop();
bind(&stack_overflow);
{
FrameScope frame(this, StackFrame::MANUAL);
CallRuntime(Runtime::kThrowStackOverflow);
break_(0xCC);
}
#else
// Check whether the expected and actual arguments count match. The registers
// are set up according to contract with ArgumentsAdaptorTrampoline:
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(actual_parameter_count));
......@@ -4497,7 +4414,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
}
#endif
bind(&regular_invoke);
}
......
......@@ -1096,14 +1096,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
Register scratch2);
// -------------------------------------------------------------------------
// Stack limit utilities
enum StackLimitKind { kInterruptStackLimit, kRealStackLimit };
void LoadStackLimit(Register destination, StackLimitKind kind);
void StackOverflowCheck(Register num_args, Register scratch1,
Register scratch2, Label* stack_overflow);
// ---------------------------------------------------------------------------
// Smi utilities.
void SmiTag(Register reg) { Addu(reg, reg, reg); }
......
......@@ -4732,107 +4732,23 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
mov(sp, dst_reg);
}
void MacroAssembler::LoadStackLimit(Register destination, StackLimitKind kind) {
DCHECK(root_array_available());
Isolate* isolate = this->isolate();
ExternalReference limit =
kind == StackLimitKind::kRealStackLimit
? ExternalReference::address_of_real_jslimit(isolate)
: ExternalReference::address_of_jslimit(isolate);
DCHECK(TurboAssembler::IsAddressableThroughRootRegister(isolate, limit));
intptr_t offset =
TurboAssembler::RootRegisterOffsetForExternalReference(isolate, limit);
CHECK(is_int32(offset));
Ld(destination, MemOperand(kRootRegister, static_cast<int32_t>(offset)));
}
void MacroAssembler::StackOverflowCheck(Register num_args, Register scratch1,
Register scratch2,
Label* stack_overflow) {
// 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.
LoadStackLimit(scratch1, StackLimitKind::kRealStackLimit);
// Make scratch1 the space we have left. The stack might already be overflowed
// here which will cause scratch1 to become negative.
dsubu(scratch1, sp, scratch1);
// Check if the arguments will overflow the stack.
dsll(scratch2, num_args, kPointerSizeLog2);
// Signed comparison.
Branch(stack_overflow, le, scratch1, Operand(scratch2));
}
void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Register actual_parameter_count,
Label* done, InvokeFlag flag) {
Label regular_invoke;
// Check whether the expected and actual arguments count match. The registers
// are set up according to contract with ArgumentsAdaptorTrampoline:
// a0: actual arguments count
// a1: function (passed through to callee)
// a2: expected arguments count
// The code below is made a lot easier because the calling code already sets
// up actual and expected registers according to the contract.
DCHECK_EQ(actual_parameter_count, a0);
DCHECK_EQ(expected_parameter_count, a2);
#ifdef V8_NO_ARGUMENTS_ADAPTOR
// If the expected parameter count is equal to the adaptor sentinel, no need
// to push undefined value as arguments.
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
// If overapplication or if the actual argument count is equal to the
// formal parameter count, no need to push extra undefined values.
Dsubu(expected_parameter_count, expected_parameter_count,
actual_parameter_count);
Branch(&regular_invoke, le, expected_parameter_count, Operand(zero_reg));
Label stack_overflow;
StackOverflowCheck(expected_parameter_count, t0, t1, &stack_overflow);
// Underapplication. Move the arguments already in the stack, including the
// receiver and the return address.
{
Label copy;
Register src = a6, dest = a7;
mov(src, sp);
dsll(t0, expected_parameter_count, kSystemPointerSizeLog2);
Dsubu(sp, sp, Operand(t0));
// Update stack pointer.
mov(dest, sp);
mov(t0, a0);
bind(&copy);
Ld(t1, MemOperand(src, 0));
Sd(t1, MemOperand(dest, 0));
Dsubu(t0, t0, Operand(1));
Daddu(src, src, Operand(kSystemPointerSize));
Daddu(dest, dest, Operand(kSystemPointerSize));
Branch(&copy, ge, t0, Operand(zero_reg));
}
// Fill remaining expected arguments with undefined values.
LoadRoot(t0, RootIndex::kUndefinedValue);
{
Label loop;
bind(&loop);
Sd(t0, MemOperand(a7, 0));
Dsubu(expected_parameter_count, expected_parameter_count, Operand(1));
Daddu(a7, a7, Operand(kSystemPointerSize));
Branch(&loop, gt, expected_parameter_count, Operand(zero_reg));
}
b(&regular_invoke);
nop();
bind(&stack_overflow);
{
FrameScope frame(this, StackFrame::MANUAL);
CallRuntime(Runtime::kThrowStackOverflow);
break_(0xCC);
}
#else
// Check whether the expected and actual arguments count match. The registers
// are set up according to contract with ArgumentsAdaptorTrampoline:
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(actual_parameter_count));
......@@ -4843,7 +4759,7 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
}
#endif
bind(&regular_invoke);
}
......
......@@ -1140,14 +1140,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
Register scratch2);
// -------------------------------------------------------------------------
// Stack limit utilities
enum StackLimitKind { kInterruptStackLimit, kRealStackLimit };
void LoadStackLimit(Register destination, StackLimitKind kind);
void StackOverflowCheck(Register num_args, Register scratch1,
Register scratch2, Label* stack_overflow);
// ---------------------------------------------------------------------------
// Smi utilities.
void SmiTag(Register dst, Register src) {
......
......@@ -4031,8 +4031,9 @@ void CodeGenerator::AssembleConstructFrame() {
}
}
void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
auto call_descriptor = linkage()->GetIncomingDescriptor();
int pop_count = static_cast<int>(call_descriptor->StackParameterCount());
const int returns = frame()->GetReturnSlotCount();
if (returns != 0) {
......@@ -4052,76 +4053,36 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
MipsOperandConverter g(this, nullptr);
const int parameter_count =
static_cast<int>(call_descriptor->StackParameterCount());
// {aditional_pop_count} is only greater than zero if {parameter_count = 0}.
// Check RawMachineAssembler::PopAndReturn.
if (parameter_count != 0) {
if (additional_pop_count->IsImmediate()) {
DCHECK_EQ(g.ToConstant(additional_pop_count).ToInt32(), 0);
} else if (__ emit_debug_code()) {
__ Assert(eq, AbortReason::kUnexpectedAdditionalPopValue,
g.ToRegister(additional_pop_count),
Operand(static_cast<int64_t>(0)));
}
}
#ifdef V8_NO_ARGUMENTS_ADAPTOR
// Functions with JS linkage have at least one parameter (the receiver).
// If {parameter_count} == 0, it means it is a builtin with
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
// itself.
const bool drop_jsargs = frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall() &&
parameter_count != 0;
#else
const bool drop_jsargs = false;
#endif
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();
} else if (frame_access_state()->has_frame()) {
// Canonicalize JSFunction return sites for now unless they have an variable
// number of stack slot pops.
if (additional_pop_count->IsImmediate() &&
g.ToConstant(additional_pop_count).ToInt32() == 0) {
if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
if (return_label_.is_bound()) {
__ Branch(&return_label_);
return;
} else {
__ bind(&return_label_);
AssembleDeconstructFrame();
}
} else {
AssembleDeconstructFrame();
}
if (drop_jsargs) {
// Get the actual argument count
__ Lw(t0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
}
AssembleDeconstructFrame();
}
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_count).
__ Addu(t0, t0, Operand(1)); // Also pop the receiver.
if (parameter_count > 1) {
Label max_number;
__ Branch(&max_number, ge, t0, Operand(parameter_count));
__ li(t0, parameter_count);
__ bind(&max_number);
}
__ sll(t0, t0, kSystemPointerSizeLog2);
__ Addu(sp, sp, t0);
} 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();
__ Drop(parameter_count + additional_count);
if (pop->IsImmediate()) {
DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
pop_count += g.ToConstant(pop).ToInt32();
} else {
Register pop_reg = g.ToRegister(additional_pop_count);
__ Drop(parameter_count);
Register pop_reg = g.ToRegister(pop);
__ sll(pop_reg, pop_reg, kSystemPointerSizeLog2);
__ Addu(sp, sp, pop_reg);
__ Addu(sp, sp, Operand(pop_reg));
}
if (pop_count != 0) {
__ DropAndRet(pop_count);
} else {
__ Ret();
}
__ Ret();
}
void CodeGenerator::FinishCode() {}
......
......@@ -4314,7 +4314,7 @@ void CodeGenerator::AssembleConstructFrame() {
}
}
void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
auto call_descriptor = linkage()->GetIncomingDescriptor();
const int returns = frame()->GetReturnSlotCount();
......@@ -4335,76 +4335,36 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
MipsOperandConverter g(this, nullptr);
const int parameter_count =
static_cast<int>(call_descriptor->StackParameterCount());
// {aditional_pop_count} is only greater than zero if {parameter_count = 0}.
// Check RawMachineAssembler::PopAndReturn.
if (parameter_count != 0) {
if (additional_pop_count->IsImmediate()) {
DCHECK_EQ(g.ToConstant(additional_pop_count).ToInt32(), 0);
} else if (__ emit_debug_code()) {
__ Assert(eq, AbortReason::kUnexpectedAdditionalPopValue,
g.ToRegister(additional_pop_count),
Operand(static_cast<int64_t>(0)));
}
}
#ifdef V8_NO_ARGUMENTS_ADAPTOR
// Functions with JS linkage have at least one parameter (the receiver).
// If {parameter_count} == 0, it means it is a builtin with
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
// itself.
const bool drop_jsargs = frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall() &&
parameter_count != 0;
#else
const bool drop_jsargs = false;
#endif
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();
} else if (frame_access_state()->has_frame()) {
// Canonicalize JSFunction return sites for now unless they have an variable
// number of stack slot pops.
if (additional_pop_count->IsImmediate() &&
g.ToConstant(additional_pop_count).ToInt32() == 0) {
if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
if (return_label_.is_bound()) {
__ Branch(&return_label_);
return;
} else {
__ bind(&return_label_);
AssembleDeconstructFrame();
}
} else {
AssembleDeconstructFrame();
}
if (drop_jsargs) {
// Get the actual argument count
__ Ld(t0, MemOperand(fp, StandardFrameConstants::kArgCOffset));
}
AssembleDeconstructFrame();
}
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_count).
__ Daddu(t0, t0, Operand(1)); // Also pop the receiver.
if (parameter_count > 1) {
Label max_number;
__ Branch(&max_number, ge, t0, Operand(parameter_count));
__ li(t0, parameter_count);
__ bind(&max_number);
}
__ dsll(t0, t0, kSystemPointerSizeLog2);
__ Daddu(sp, sp, t0);
} 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();
__ Drop(parameter_count + additional_count);
int pop_count = static_cast<int>(call_descriptor->StackParameterCount());
if (pop->IsImmediate()) {
pop_count += g.ToConstant(pop).ToInt32();
} else {
Register pop_reg = g.ToRegister(additional_pop_count);
__ Drop(parameter_count);
Register pop_reg = g.ToRegister(pop);
__ dsll(pop_reg, pop_reg, kSystemPointerSizeLog2);
__ Daddu(sp, sp, pop_reg);
}
__ Ret();
if (pop_count != 0) {
__ DropAndRet(pop_count);
} else {
__ Ret();
}
}
void CodeGenerator::FinishCode() {}
......
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