Commit 99c9e635 authored by Zhao Jiazhong's avatar Zhao Jiazhong Committed by Commit Bot

[mips][builtins] Remove ParameterCount uses from InvokeFunction(Code)

port 46648402 https://crrev.com/c/1871605

Original Commit Message:

CallDebugOnFunctionCall was always using Registers and not Immediates.
    Then ParameterCount is not really needed. Since updating that, we
    could update other functions, e.g InvokeFunction, to only use
    registers too.

    Also removed now irrelevant variables, e.g definitely_mismatches.

[mips][codegen] Removed ParameterCount class

port 1e696896 https://crrev.com/c/1886916

Original Commit Message:

    It was used only with Register inputs, so we can replace its uses with
    the Registers themselves.

Change-Id: I0a661519f5602bf4d52c40c6c238436b93b71664
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1898826Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64753}
parent e554dec4
......@@ -122,8 +122,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// a0: number of arguments (untagged)
// a1: constructor function
// a3: new target
ParameterCount actual(a0);
__ InvokeFunction(a1, a3, actual, CALL_FUNCTION);
__ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION);
// Restore context from the frame.
__ lw(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
......@@ -279,8 +278,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ Branch(&loop, greater_equal, t3, Operand(zero_reg));
// Call the function.
ParameterCount actual(a0);
__ InvokeFunction(a1, a3, actual, CALL_FUNCTION);
__ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION);
// ----------- S t a t e -------------
// -- v0: constructor result
......@@ -1999,9 +1997,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ lhu(a2,
FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(a0);
ParameterCount expected(a2);
__ InvokeFunctionCode(a1, no_reg, expected, actual, JUMP_FUNCTION);
__ InvokeFunctionCode(a1, no_reg, a2, a0, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
......
......@@ -122,8 +122,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// a0: number of arguments (untagged)
// a1: constructor function
// a3: new target
ParameterCount actual(a0);
__ InvokeFunction(a1, a3, actual, CALL_FUNCTION);
__ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION);
// Restore context from the frame.
__ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
......@@ -280,8 +279,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ Branch(&loop, greater_equal, t3, Operand(zero_reg));
// Call the function.
ParameterCount actual(a0);
__ InvokeFunction(a1, a3, actual, CALL_FUNCTION);
__ InvokeFunctionWithNewTarget(a1, a3, a0, CALL_FUNCTION);
// ----------- S t a t e -------------
// -- v0: constructor result
......@@ -2040,9 +2038,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ Lhu(a2,
FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(a0);
ParameterCount expected(a2);
__ InvokeFunctionCode(a1, no_reg, expected, actual, JUMP_FUNCTION);
__ InvokeFunctionCode(a1, no_reg, a2, a0, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
......
......@@ -4270,35 +4270,21 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1,
// -----------------------------------------------------------------------------
// JavaScript invokes.
void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count_reg,
void TurboAssembler::PrepareForTailCall(Register callee_args_count,
Register caller_args_count,
Register scratch0, Register scratch1) {
#if DEBUG
if (callee_args_count.is_reg()) {
DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
scratch1));
} else {
DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
}
#endif
// Calculate the end of destination area where we will put the arguments
// after we drop current frame. We add kPointerSize to count the receiver
// argument which is not included into formal parameters count.
Register dst_reg = scratch0;
Lsa(dst_reg, fp, caller_args_count_reg, kPointerSizeLog2);
Lsa(dst_reg, fp, caller_args_count, kPointerSizeLog2);
Addu(dst_reg, dst_reg,
Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
Register src_reg = caller_args_count_reg;
Register src_reg = caller_args_count;
// Calculate the end of source area. +kPointerSize is for the receiver.
if (callee_args_count.is_reg()) {
Lsa(src_reg, sp, callee_args_count.reg(), kPointerSizeLog2);
Addu(src_reg, src_reg, Operand(kPointerSize));
} else {
Addu(src_reg, sp,
Operand((callee_args_count.immediate() + 1) * kPointerSize));
}
Lsa(src_reg, sp, callee_args_count, kPointerSizeLog2);
Addu(src_reg, src_reg, Operand(kPointerSize));
if (FLAG_debug_code) {
Check(lo, AbortReason::kStackAccessBelowStackPointer, src_reg,
......@@ -4330,68 +4316,39 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
mov(sp, dst_reg);
}
void MacroAssembler::InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches,
InvokeFlag flag) {
bool definitely_matches = false;
*definitely_mismatches = false;
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. If not,
// setup registers according to contract with ArgumentsAdaptorTrampoline:
// 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 if values are
// passed in registers.
DCHECK(actual.is_immediate() || actual.reg() == a0);
DCHECK(expected.is_immediate() || expected.reg() == a2);
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
li(a0, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
// don't want that done. Skip adaption code by making it look
// like we have a match between expected and actual number of
// arguments.
definitely_matches = true;
} else {
*definitely_mismatches = true;
li(a2, Operand(expected.immediate()));
}
}
} else if (actual.is_immediate()) {
li(a0, Operand(actual.immediate()));
Branch(&regular_invoke, eq, expected.reg(), Operand(a0));
// up actual and expected registers according to the contract.
DCHECK_EQ(actual_parameter_count, a0);
DCHECK_EQ(expected_parameter_count, a2);
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(actual_parameter_count));
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) {
Call(adaptor);
Branch(done);
} else {
Branch(&regular_invoke, eq, expected.reg(), Operand(actual.reg()));
Jump(adaptor, RelocInfo::CODE_TARGET);
}
if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) {
Call(adaptor);
if (!*definitely_mismatches) {
Branch(done);
}
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
}
bind(&regular_invoke);
}
bind(&regular_invoke);
}
void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual) {
Register expected_parameter_count,
Register actual_parameter_count) {
Label skip_hook;
li(t0, ExternalReference::debug_hook_on_function_call_address(isolate()));
lb(t0, MemOperand(t0));
......@@ -4399,22 +4356,16 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
{
// Load receiver to pass it later to DebugOnFunctionCall hook.
if (actual.is_reg()) {
Lsa(at, sp, actual.reg(), kPointerSizeLog2);
lw(t0, MemOperand(at));
} else {
lw(t0, MemOperand(sp, actual.immediate() << kPointerSizeLog2));
}
Lsa(at, sp, actual_parameter_count, kPointerSizeLog2);
lw(t0, MemOperand(at));
FrameScope frame(this,
has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) {
SmiTag(expected.reg());
Push(expected.reg());
}
if (actual.is_reg()) {
SmiTag(actual.reg());
Push(actual.reg());
}
SmiTag(expected_parameter_count);
Push(expected_parameter_count);
SmiTag(actual_parameter_count);
Push(actual_parameter_count);
if (new_target.is_valid()) {
Push(new_target);
}
......@@ -4426,29 +4377,28 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
if (new_target.is_valid()) {
Pop(new_target);
}
if (actual.is_reg()) {
Pop(actual.reg());
SmiUntag(actual.reg());
}
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
Pop(actual_parameter_count);
SmiUntag(actual_parameter_count);
Pop(expected_parameter_count);
SmiUntag(expected_parameter_count);
}
bind(&skip_hook);
}
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual,
Register expected_parameter_count,
Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK(function == a1);
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
DCHECK_EQ(function, a1);
DCHECK_IMPLIES(new_target.is_valid(), new_target == a3);
// On function call, call into the debugger if necessary.
CheckDebugHook(function, new_target, expected, actual);
CheckDebugHook(function, new_target, expected_parameter_count,
actual_parameter_count);
// Clear the new.target register if not given.
if (!new_target.is_valid()) {
......@@ -4456,36 +4406,34 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
}
Label done;
bool definitely_mismatches = false;
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag);
if (!definitely_mismatches) {
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
Register code = kJavaScriptCallCodeStartRegister;
lw(code, FieldMemOperand(function, JSFunction::kCodeOffset));
if (flag == CALL_FUNCTION) {
Addu(code, code, Code::kHeaderSize - kHeapObjectTag);
Call(code);
} else {
DCHECK(flag == JUMP_FUNCTION);
Addu(code, code, Code::kHeaderSize - kHeapObjectTag);
Jump(code);
}
// Continue here if InvokePrologue does handle the invocation due to
// mismatched parameter counts.
bind(&done);
}
InvokePrologue(expected_parameter_count, actual_parameter_count, &done, flag);
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
Register code = kJavaScriptCallCodeStartRegister;
lw(code, FieldMemOperand(function, JSFunction::kCodeOffset));
if (flag == CALL_FUNCTION) {
Addu(code, code, Code::kHeaderSize - kHeapObjectTag);
Call(code);
} else {
DCHECK(flag == JUMP_FUNCTION);
Addu(code, code, Code::kHeaderSize - kHeapObjectTag);
Jump(code);
}
// Continue here if InvokePrologue does handle the invocation due to
// mismatched parameter counts.
bind(&done);
}
void MacroAssembler::InvokeFunction(Register function, Register new_target,
const ParameterCount& actual,
InvokeFlag flag) {
void MacroAssembler::InvokeFunctionWithNewTarget(
Register function, Register new_target, Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
// Contract with called JS functions requires that function is passed in a1.
DCHECK(function == a1);
DCHECK_EQ(function, a1);
Register expected_reg = a2;
Register temp_reg = t0;
......@@ -4495,24 +4443,25 @@ void MacroAssembler::InvokeFunction(Register function, Register new_target,
FieldMemOperand(temp_reg,
SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount expected(expected_reg);
InvokeFunctionCode(function, new_target, expected, actual, flag);
InvokeFunctionCode(function, new_target, expected_reg, actual_parameter_count,
flag);
}
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& expected,
const ParameterCount& actual,
Register expected_parameter_count,
Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
// Contract with called JS functions requires that function is passed in a1.
DCHECK(function == a1);
DCHECK_EQ(function, a1);
// Get the function and setup the context.
lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
InvokeFunctionCode(a1, no_reg, expected, actual, flag);
InvokeFunctionCode(a1, no_reg, expected_parameter_count,
actual_parameter_count, flag);
}
// ---------------------------------------------------------------------------
......
......@@ -443,11 +443,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Removes current frame and its arguments from the stack preserving
// the arguments and a return address pushed to the stack for the next call.
// Both |callee_args_count| and |caller_args_count_reg| do not include
// receiver. |callee_args_count| is not modified, |caller_args_count_reg|
// Both |callee_args_count| and |caller_args_count| do not include
// receiver. |callee_args_count| is not modified. |caller_args_count|
// is trashed.
void PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count_reg, Register scratch0,
void PrepareForTailCall(Register callee_args_count,
Register caller_args_count, Register scratch0,
Register scratch1);
int CalculateStackPassedWords(int num_reg_arguments,
......@@ -988,21 +988,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Invoke the JavaScript function code by either calling or jumping.
void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// On function call, call into the debugger if necessary.
void CheckDebugHook(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual);
Register expected_parameter_count,
Register actual_parameter_count);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag);
void InvokeFunctionWithNewTarget(Register function, Register new_target,
Register actual_parameter_count,
InvokeFlag flag);
void InvokeFunction(Register function, const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support.
void MaybeDropFrames();
......@@ -1114,9 +1115,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
private:
// Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches, InvokeFlag flag);
void InvokePrologue(Register expected_parameter_count,
Register actual_parameter_count, Label* done,
InvokeFlag flag);
// Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code);
......
......@@ -4583,35 +4583,21 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1,
// -----------------------------------------------------------------------------
// JavaScript invokes.
void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count_reg,
void TurboAssembler::PrepareForTailCall(Register callee_args_count,
Register caller_args_count,
Register scratch0, Register scratch1) {
#if DEBUG
if (callee_args_count.is_reg()) {
DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
scratch1));
} else {
DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
}
#endif
// Calculate the end of destination area where we will put the arguments
// after we drop current frame. We add kPointerSize to count the receiver
// argument which is not included into formal parameters count.
Register dst_reg = scratch0;
Dlsa(dst_reg, fp, caller_args_count_reg, kPointerSizeLog2);
Dlsa(dst_reg, fp, caller_args_count, kPointerSizeLog2);
Daddu(dst_reg, dst_reg,
Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
Register src_reg = caller_args_count_reg;
Register src_reg = caller_args_count;
// Calculate the end of source area. +kPointerSize is for the receiver.
if (callee_args_count.is_reg()) {
Dlsa(src_reg, sp, callee_args_count.reg(), kPointerSizeLog2);
Daddu(src_reg, src_reg, Operand(kPointerSize));
} else {
Daddu(src_reg, sp,
Operand((callee_args_count.immediate() + 1) * kPointerSize));
}
Dlsa(src_reg, sp, callee_args_count, kPointerSizeLog2);
Daddu(src_reg, src_reg, Operand(kPointerSize));
if (FLAG_debug_code) {
Check(lo, AbortReason::kStackAccessBelowStackPointer, src_reg,
......@@ -4643,68 +4629,40 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
mov(sp, dst_reg);
}
void MacroAssembler::InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches,
InvokeFlag flag) {
bool definitely_matches = false;
*definitely_mismatches = false;
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. If not,
// setup registers according to contract with ArgumentsAdaptorTrampoline:
// 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 if values are
// passed in registers.
DCHECK(actual.is_immediate() || actual.reg() == a0);
DCHECK(expected.is_immediate() || expected.reg() == a2);
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
li(a0, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
// don't want that done. Skip adaption code by making it look
// like we have a match between expected and actual number of
// arguments.
definitely_matches = true;
} else {
*definitely_mismatches = true;
li(a2, Operand(expected.immediate()));
}
}
} else if (actual.is_immediate()) {
li(a0, Operand(actual.immediate()));
Branch(&regular_invoke, eq, expected.reg(), Operand(a0));
// up actual and expected registers according to the contract.
DCHECK_EQ(actual_parameter_count, a0);
DCHECK_EQ(expected_parameter_count, a2);
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(actual_parameter_count));
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) {
Call(adaptor);
Branch(done);
} else {
Branch(&regular_invoke, eq, expected.reg(), Operand(actual.reg()));
Jump(adaptor, RelocInfo::CODE_TARGET);
}
if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) {
Call(adaptor);
if (!*definitely_mismatches) {
Branch(done);
}
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
}
bind(&regular_invoke);
}
bind(&regular_invoke);
}
void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual) {
Register expected_parameter_count,
Register actual_parameter_count) {
Label skip_hook;
li(t0, ExternalReference::debug_hook_on_function_call_address(isolate()));
......@@ -4713,22 +4671,16 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
{
// Load receiver to pass it later to DebugOnFunctionCall hook.
if (actual.is_reg()) {
Dlsa(t0, sp, actual.reg(), kPointerSizeLog2);
Ld(t0, MemOperand(t0));
} else {
Ld(t0, MemOperand(sp, actual.immediate() << kPointerSizeLog2));
}
Dlsa(t0, sp, actual_parameter_count, kPointerSizeLog2);
Ld(t0, MemOperand(t0));
FrameScope frame(this,
has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) {
SmiTag(expected.reg());
Push(expected.reg());
}
if (actual.is_reg()) {
SmiTag(actual.reg());
Push(actual.reg());
}
SmiTag(expected_parameter_count);
Push(expected_parameter_count);
SmiTag(actual_parameter_count);
Push(actual_parameter_count);
if (new_target.is_valid()) {
Push(new_target);
}
......@@ -4740,29 +4692,28 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
if (new_target.is_valid()) {
Pop(new_target);
}
if (actual.is_reg()) {
Pop(actual.reg());
SmiUntag(actual.reg());
}
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
Pop(actual_parameter_count);
SmiUntag(actual_parameter_count);
Pop(expected_parameter_count);
SmiUntag(expected_parameter_count);
}
bind(&skip_hook);
}
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual,
Register expected_parameter_count,
Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK(function == a1);
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
DCHECK_EQ(function, a1);
DCHECK_IMPLIES(new_target.is_valid(), new_target == a3);
// On function call, call into the debugger if necessary.
CheckDebugHook(function, new_target, expected, actual);
CheckDebugHook(function, new_target, expected_parameter_count,
actual_parameter_count);
// Clear the new.target register if not given.
if (!new_target.is_valid()) {
......@@ -4770,62 +4721,62 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
}
Label done;
bool definitely_mismatches = false;
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag);
if (!definitely_mismatches) {
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
Register code = kJavaScriptCallCodeStartRegister;
Ld(code, FieldMemOperand(function, JSFunction::kCodeOffset));
if (flag == CALL_FUNCTION) {
Daddu(code, code, Operand(Code::kHeaderSize - kHeapObjectTag));
Call(code);
} else {
DCHECK(flag == JUMP_FUNCTION);
Daddu(code, code, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(code);
}
// Continue here if InvokePrologue does handle the invocation due to
// mismatched parameter counts.
bind(&done);
}
InvokePrologue(expected_parameter_count, actual_parameter_count, &done, flag);
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
Register code = kJavaScriptCallCodeStartRegister;
Ld(code, FieldMemOperand(function, JSFunction::kCodeOffset));
if (flag == CALL_FUNCTION) {
Daddu(code, code, Operand(Code::kHeaderSize - kHeapObjectTag));
Call(code);
} else {
DCHECK(flag == JUMP_FUNCTION);
Daddu(code, code, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(code);
}
// Continue here if InvokePrologue does handle the invocation due to
// mismatched parameter counts.
bind(&done);
}
void MacroAssembler::InvokeFunction(Register function, Register new_target,
const ParameterCount& actual,
InvokeFlag flag) {
void MacroAssembler::InvokeFunctionWithNewTarget(
Register function, Register new_target, Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
// Contract with called JS functions requires that function is passed in a1.
DCHECK(function == a1);
Register expected_reg = a2;
DCHECK_EQ(function, a1);
Register expected_parameter_count = a2;
Register temp_reg = t0;
Ld(temp_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
Ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// The argument count is stored as uint16_t
Lhu(expected_reg,
Lhu(expected_parameter_count,
FieldMemOperand(temp_reg,
SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount expected(expected_reg);
InvokeFunctionCode(a1, new_target, expected, actual, flag);
InvokeFunctionCode(a1, new_target, expected_parameter_count,
actual_parameter_count, flag);
}
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& expected,
const ParameterCount& actual,
Register expected_parameter_count,
Register actual_parameter_count,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
// Contract with called JS functions requires that function is passed in a1.
DCHECK(function == a1);
DCHECK_EQ(function, a1);
// Get the function and setup the context.
Ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
InvokeFunctionCode(a1, no_reg, expected, actual, flag);
InvokeFunctionCode(a1, no_reg, expected_parameter_count,
actual_parameter_count, flag);
}
// ---------------------------------------------------------------------------
......
......@@ -466,11 +466,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Removes current frame and its arguments from the stack preserving
// the arguments and a return address pushed to the stack for the next call.
// Both |callee_args_count| and |caller_args_count_reg| do not include
// receiver. |callee_args_count| is not modified, |caller_args_count_reg|
// Both |callee_args_count| and |caller_args_count| do not include
// receiver. |callee_args_count| is not modified. |caller_args_count|
// is trashed.
void PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count_reg, Register scratch0,
void PrepareForTailCall(Register callee_args_count,
Register caller_args_count, Register scratch0,
Register scratch1);
int CalculateStackPassedWords(int num_reg_arguments,
......@@ -1029,21 +1029,21 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Invoke the JavaScript function code by either calling or jumping.
void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// On function call, call into the debugger if necessary.
void CheckDebugHook(Register fun, Register new_target,
const ParameterCount& expected,
const ParameterCount& actual);
Register expected_parameter_count,
Register actual_parameter_count);
// Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag);
void InvokeFunction(Register function, const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
void InvokeFunctionWithNewTarget(Register function, Register new_target,
Register actual_parameter_count,
InvokeFlag flag);
void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// Frame restart support.
void MaybeDropFrames();
......@@ -1175,9 +1175,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
private:
// Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches, InvokeFlag flag);
void InvokePrologue(Register expected_parameter_count,
Register actual_parameter_count, Label* done,
InvokeFlag flag);
// Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code);
......
......@@ -557,9 +557,7 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(caller_args_count_reg);
ParameterCount callee_args_count(args_reg);
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
scratch3);
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
__ bind(&done);
}
......
......@@ -528,9 +528,7 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(caller_args_count_reg);
ParameterCount callee_args_count(args_reg);
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
scratch3);
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3);
__ bind(&done);
}
......
......@@ -43,9 +43,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(a2, a0);
ParameterCount dummy1(a2);
ParameterCount dummy2(a0);
__ InvokeFunction(a1, dummy1, dummy2, JUMP_FUNCTION);
__ InvokeFunction(a1, a2, a0, JUMP_FUNCTION);
}
......
......@@ -43,9 +43,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(a2, a0);
ParameterCount dummy1(a2);
ParameterCount dummy2(a0);
__ InvokeFunction(a1, dummy1, dummy2, JUMP_FUNCTION);
__ InvokeFunction(a1, a2, a0, JUMP_FUNCTION);
}
......
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