Commit 46648402 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[builtins] Remove ParameterCount uses from InvokeFunction(Code)

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.

Bug: v8:9771
Change-Id: I83382c146dd47ccb8bb329f5becb5e941e4c3968
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1871605Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64616}
parent 100850c9
...@@ -147,8 +147,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -147,8 +147,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// r0: number of arguments (untagged) // r0: number of arguments (untagged)
// r1: constructor function // r1: constructor function
// r3: new target // r3: new target
ParameterCount actual(r0); __ InvokeFunctionWithNewTarget(r1, r3, r0, CALL_FUNCTION);
__ InvokeFunction(r1, r3, actual, CALL_FUNCTION);
// Restore context from the frame. // Restore context from the frame.
__ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
...@@ -294,8 +293,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -294,8 +293,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ b(ge, &loop); __ b(ge, &loop);
// Call the function. // Call the function.
ParameterCount actual(r0); __ InvokeFunctionWithNewTarget(r1, r3, r0, CALL_FUNCTION);
__ InvokeFunction(r1, r3, actual, CALL_FUNCTION);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r0: constructor result // -- r0: constructor result
...@@ -2017,9 +2015,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2017,9 +2015,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ ldrh(r2, __ ldrh(r2,
FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(r0); __ InvokeFunctionCode(r1, no_reg, r2, r0, JUMP_FUNCTION);
ParameterCount expected(r2);
__ InvokeFunctionCode(r1, no_reg, expected, actual, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception. // The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor); __ bind(&class_constructor);
......
...@@ -183,8 +183,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -183,8 +183,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Call the function. // Call the function.
ParameterCount actual(argc); __ InvokeFunctionWithNewTarget(x1, x3, argc, CALL_FUNCTION);
__ InvokeFunction(x1, x3, actual, CALL_FUNCTION);
// Restore the context from the frame. // Restore the context from the frame.
__ Ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); __ Ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
...@@ -345,8 +344,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -345,8 +344,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Call the function. // Call the function.
__ Mov(x0, x12); __ Mov(x0, x12);
ParameterCount actual(x0); __ InvokeFunctionWithNewTarget(x1, x3, x0, CALL_FUNCTION);
__ InvokeFunction(x1, x3, actual, CALL_FUNCTION);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- sp[0*kSystemPointerSize]: implicit receiver // -- sp[0*kSystemPointerSize]: implicit receiver
...@@ -2424,9 +2422,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2424,9 +2422,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ Ldrh(x2, __ Ldrh(x2,
FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(x0); __ InvokeFunctionCode(x1, no_reg, x2, x0, JUMP_FUNCTION);
ParameterCount expected(x2);
__ InvokeFunctionCode(x1, no_reg, expected, actual, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception. // The function is a "classConstructor", need to raise an exception.
__ Bind(&class_constructor); __ Bind(&class_constructor);
......
...@@ -141,10 +141,9 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -141,10 +141,9 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// eax: number of arguments (untagged) // eax: number of arguments (untagged)
// edi: constructor function // edi: constructor function
// edx: new target // edx: new target
ParameterCount actual(eax);
// Reload context from the frame. // Reload context from the frame.
__ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset));
__ InvokeFunction(edi, edx, actual, CALL_FUNCTION); __ InvokeFunction(edi, edx, eax, CALL_FUNCTION);
// Restore context from the frame. // Restore context from the frame.
__ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset));
...@@ -298,8 +297,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -298,8 +297,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Restore and and call the constructor function. // Restore and and call the constructor function.
__ mov(edi, Operand(ebp, ConstructFrameConstants::kConstructorOffset)); __ mov(edi, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
ParameterCount actual(eax); __ InvokeFunction(edi, edx, eax, CALL_FUNCTION);
__ InvokeFunction(edi, edx, actual, CALL_FUNCTION);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- eax: constructor result // -- eax: constructor result
...@@ -2154,9 +2152,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2154,9 +2152,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ movzx_w( __ movzx_w(
ecx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); ecx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(eax); __ InvokeFunctionCode(edi, no_reg, ecx, eax, JUMP_FUNCTION);
ParameterCount expected(ecx);
__ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception. // The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor); __ bind(&class_constructor);
{ {
......
...@@ -146,8 +146,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -146,8 +146,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// rax: number of arguments (untagged) // rax: number of arguments (untagged)
// rdi: constructor function // rdi: constructor function
// rdx: new target // rdx: new target
ParameterCount actual(rax); __ InvokeFunction(rdi, rdx, rax, CALL_FUNCTION);
__ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION);
// Restore context from the frame. // Restore context from the frame.
__ movq(rsi, Operand(rbp, ConstructFrameConstants::kContextOffset)); __ movq(rsi, Operand(rbp, ConstructFrameConstants::kContextOffset));
...@@ -299,8 +298,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -299,8 +298,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ j(greater_equal, &loop, Label::kNear); __ j(greater_equal, &loop, Label::kNear);
// Call the function. // Call the function.
ParameterCount actual(rax); __ InvokeFunction(rdi, rdx, rax, CALL_FUNCTION);
__ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax constructor result // -- rax constructor result
...@@ -2275,10 +2273,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2275,10 +2273,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ movzxwq( __ movzxwq(
rbx, FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); rbx, FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount actual(rax);
ParameterCount expected(rbx);
__ InvokeFunctionCode(rdi, no_reg, expected, actual, JUMP_FUNCTION); __ InvokeFunctionCode(rdi, no_reg, rbx, rax, JUMP_FUNCTION);
// The function is a "classConstructor", need to raise an exception. // The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor); __ bind(&class_constructor);
......
...@@ -1553,12 +1553,9 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, ...@@ -1553,12 +1553,9 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
mov(sp, dst_reg); mov(sp, dst_reg);
} }
void MacroAssembler::InvokePrologue(const ParameterCount& expected, void MacroAssembler::InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count,
bool* definitely_mismatches, Label* done, InvokeFlag flag) {
InvokeFlag flag) {
bool definitely_matches = false;
*definitely_mismatches = false;
Label regular_invoke; Label regular_invoke;
// Check whether the expected and actual arguments count match. If not, // Check whether the expected and actual arguments count match. If not,
...@@ -1568,72 +1565,36 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, ...@@ -1568,72 +1565,36 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
// r2: expected arguments count // r2: expected arguments count
// The code below is made a lot easier because the calling code already sets // 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 // up actual and expected registers according to the contract.
// passed in registers. DCHECK_EQ(actual_parameter_count, r0);
DCHECK(actual.is_immediate() || actual.reg() == r0); DCHECK_EQ(expected_parameter_count, r2);
DCHECK(expected.is_immediate() || expected.reg() == r2);
cmp(expected_parameter_count, actual_parameter_count);
if (expected.is_immediate()) { b(eq, &regular_invoke);
DCHECK(actual.is_immediate());
mov(r0, Operand(actual.immediate())); Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (expected.immediate() == actual.immediate()) { if (flag == CALL_FUNCTION) {
definitely_matches = true; Call(adaptor);
} else { b(done);
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;
mov(r2, Operand(expected.immediate()));
}
}
} else { } else {
if (actual.is_immediate()) { Jump(adaptor, RelocInfo::CODE_TARGET);
mov(r0, Operand(actual.immediate()));
cmp(expected.reg(), Operand(actual.immediate()));
b(eq, &regular_invoke);
} else {
cmp(expected.reg(), Operand(actual.reg()));
b(eq, &regular_invoke);
}
} }
if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) {
Call(adaptor);
if (!*definitely_mismatches) {
b(done);
}
} else {
Jump(adaptor, RelocInfo::CODE_TARGET);
}
bind(&regular_invoke); bind(&regular_invoke);
}
} }
void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual) { Register actual_parameter_count) {
// Load receiver to pass it later to DebugOnFunctionCall hook. // Load receiver to pass it later to DebugOnFunctionCall hook.
if (actual.is_reg()) { ldr(r4, MemOperand(sp, actual_parameter_count, LSL, kPointerSizeLog2));
ldr(r4, MemOperand(sp, actual.reg(), LSL, kPointerSizeLog2));
} else {
ldr(r4, MemOperand(sp, actual.immediate() << kPointerSizeLog2));
}
FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) {
SmiTag(expected.reg()); SmiTag(expected_parameter_count);
Push(expected.reg()); Push(expected_parameter_count);
}
if (actual.is_reg()) { SmiTag(actual_parameter_count);
SmiTag(actual.reg()); Push(actual_parameter_count);
Push(actual.reg());
}
if (new_target.is_valid()) { if (new_target.is_valid()) {
Push(new_target); Push(new_target);
} }
...@@ -1645,23 +1606,21 @@ void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, ...@@ -1645,23 +1606,21 @@ void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target,
if (new_target.is_valid()) { if (new_target.is_valid()) {
Pop(new_target); Pop(new_target);
} }
if (actual.is_reg()) {
Pop(actual.reg()); Pop(actual_parameter_count);
SmiUntag(actual.reg()); SmiUntag(actual_parameter_count);
}
if (expected.is_reg()) { Pop(expected_parameter_count);
Pop(expected.reg()); SmiUntag(expected_parameter_count);
SmiUntag(expected.reg());
}
} }
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK_IMPLIES(flag == CALL_FUNCTION, has_frame());
DCHECK(function == r1); DCHECK_EQ(function, r1);
DCHECK_IMPLIES(new_target.is_valid(), new_target == r3); DCHECK_IMPLIES(new_target.is_valid(), new_target == r3);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
...@@ -1682,26 +1641,24 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -1682,26 +1641,24 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
} }
Label done; Label done;
bool definitely_mismatches = false; InvokePrologue(expected_parameter_count, actual_parameter_count, &done, flag);
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag); // We call indirectly through the code field in the function to
if (!definitely_mismatches) { // allow recompilation to take effect without changing any of the
// We call indirectly through the code field in the function to // call sites.
// allow recompilation to take effect without changing any of the Register code = kJavaScriptCallCodeStartRegister;
// call sites. ldr(code, FieldMemOperand(function, JSFunction::kCodeOffset));
Register code = kJavaScriptCallCodeStartRegister; if (flag == CALL_FUNCTION) {
ldr(code, FieldMemOperand(function, JSFunction::kCodeOffset)); CallCodeObject(code);
if (flag == CALL_FUNCTION) { } else {
CallCodeObject(code); DCHECK(flag == JUMP_FUNCTION);
} else { JumpCodeObject(code);
DCHECK(flag == JUMP_FUNCTION);
JumpCodeObject(code);
}
} }
b(&done); b(&done);
// Deferred debug hook. // Deferred debug hook.
bind(&debug_hook); bind(&debug_hook);
CallDebugOnFunctionCall(function, new_target, expected, actual); CallDebugOnFunctionCall(function, new_target, expected_parameter_count,
actual_parameter_count);
b(&continue_after_hook); b(&continue_after_hook);
// Continue here if InvokePrologue does handle the invocation due to // Continue here if InvokePrologue does handle the invocation due to
...@@ -1709,14 +1666,14 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -1709,14 +1666,14 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
bind(&done); bind(&done);
} }
void MacroAssembler::InvokeFunction(Register fun, Register new_target, void MacroAssembler::InvokeFunctionWithNewTarget(
const ParameterCount& actual, Register fun, Register new_target, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // 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 r1. // Contract with called JS functions requires that function is passed in r1.
DCHECK(fun == r1); DCHECK_EQ(fun, r1);
Register expected_reg = r2; Register expected_reg = r2;
Register temp_reg = r4; Register temp_reg = r4;
...@@ -1727,24 +1684,25 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target, ...@@ -1727,24 +1684,25 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target,
FieldMemOperand(temp_reg, FieldMemOperand(temp_reg,
SharedFunctionInfo::kFormalParameterCountOffset)); SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount expected(expected_reg); InvokeFunctionCode(fun, new_target, expected_reg, actual_parameter_count,
InvokeFunctionCode(fun, new_target, expected, actual, flag); flag);
} }
void MacroAssembler::InvokeFunction(Register function, void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // 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 r1. // Contract with called JS functions requires that function is passed in r1.
DCHECK(function == r1); DCHECK_EQ(function, r1);
// Get the function and setup the context. // Get the function and setup the context.
ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
InvokeFunctionCode(r1, no_reg, expected, actual, flag); InvokeFunctionCode(r1, no_reg, expected_parameter_count,
actual_parameter_count, flag);
} }
void MacroAssembler::MaybeDropFrames() { void MacroAssembler::MaybeDropFrames() {
......
...@@ -635,21 +635,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -635,21 +635,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Invoke the JavaScript function code by either calling or jumping. // Invoke the JavaScript function code by either calling or jumping.
void InvokeFunctionCode(Register function, Register new_target, void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// On function call, call into the debugger. // On function call, call into the debugger.
void CallDebugOnFunctionCall(Register fun, Register new_target, void CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual); Register actual_parameter_count);
// Invoke the JavaScript function in the given register. Changes the // Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking. // current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target, void InvokeFunctionWithNewTarget(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count,
InvokeFlag flag);
void InvokeFunction(Register function, const ParameterCount& expected, void InvokeFunction(Register function, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// Frame restart support // Frame restart support
void MaybeDropFrames(); void MaybeDropFrames();
...@@ -796,9 +797,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -796,9 +797,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
private: private:
// Helper functions for generating invokes. // Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected, void InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count, Label* done,
bool* definitely_mismatches, InvokeFlag flag); InvokeFlag flag);
// Compute memory operands for safepoint stack slots. // Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code); static int SafepointRegisterStackIndex(int reg_code);
......
This diff is collapsed.
...@@ -1787,23 +1787,24 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -1787,23 +1787,24 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// 'actual' must use an immediate or x0. // 'actual' must use an immediate or x0.
// 'expected' must use an immediate or x2. // 'expected' must use an immediate or x2.
// 'call_kind' must be x5. // 'call_kind' must be x5.
void InvokePrologue(const ParameterCount& expected, void InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count, Label* done,
InvokeFlag flag, bool* definitely_mismatches); InvokeFlag flag);
// On function call, call into the debugger. // On function call, call into the debugger.
void CallDebugOnFunctionCall(Register fun, Register new_target, void CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual); Register actual_parameter_count);
void InvokeFunctionCode(Register function, Register new_target, void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// Invoke the JavaScript function in the given register. // Invoke the JavaScript function in the given register.
// Changes the current context to the context in the function before invoking. // Changes the current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target, void InvokeFunctionWithNewTarget(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count,
void InvokeFunction(Register function, const ParameterCount& expected, InvokeFlag flag);
const ParameterCount& actual, InvokeFlag flag); void InvokeFunction(Register function, Register expected_parameter_count,
Register actual_parameter_count, InvokeFlag flag);
// ---- Code generation helpers ---- // ---- Code generation helpers ----
......
...@@ -1104,121 +1104,70 @@ void TurboAssembler::PrepareForTailCall( ...@@ -1104,121 +1104,70 @@ void TurboAssembler::PrepareForTailCall(
mov(esp, new_sp_reg); mov(esp, new_sp_reg);
} }
void MacroAssembler::InvokePrologue(const ParameterCount& expected, void MacroAssembler::InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count,
bool* definitely_mismatches, Label* done, InvokeFlag flag) {
InvokeFlag flag, DCHECK_EQ(actual_parameter_count, eax);
Label::Distance done_near) {
DCHECK_IMPLIES(expected.is_reg(), expected.reg() == ecx); if (expected_parameter_count != actual_parameter_count) {
DCHECK_IMPLIES(actual.is_reg(), actual.reg() == eax); DCHECK_EQ(expected_parameter_count, ecx);
bool definitely_matches = false;
*definitely_mismatches = false;
Label invoke;
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
mov(eax, 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;
mov(ecx, expected.immediate());
}
}
} else {
if (actual.is_immediate()) {
// Expected is in register, actual is immediate. This is the
// case when we invoke function values without going through the
// IC mechanism.
mov(eax, actual.immediate());
cmp(expected.reg(), actual.immediate());
j(equal, &invoke);
DCHECK(expected.reg() == ecx);
} else if (expected.reg() != actual.reg()) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
cmp(expected.reg(), actual.reg());
j(equal, &invoke);
DCHECK(actual.reg() == eax);
DCHECK(expected.reg() == ecx);
} else {
definitely_matches = true;
Move(eax, actual.reg());
}
}
if (!definitely_matches) { Label regular_invoke;
cmp(expected_parameter_count, actual_parameter_count);
j(equal, &regular_invoke);
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline); Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) { if (flag == CALL_FUNCTION) {
Call(adaptor, RelocInfo::CODE_TARGET); Call(adaptor, RelocInfo::CODE_TARGET);
if (!*definitely_mismatches) { jmp(done, Label::kNear);
jmp(done, done_near);
}
} else { } else {
Jump(adaptor, RelocInfo::CODE_TARGET); Jump(adaptor, RelocInfo::CODE_TARGET);
} }
bind(&invoke); bind(&regular_invoke);
} }
} }
void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual) { Register actual_parameter_count) {
FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) { SmiTag(expected_parameter_count);
SmiTag(expected.reg()); Push(expected_parameter_count);
Push(expected.reg());
} SmiTag(actual_parameter_count);
if (actual.is_reg()) { Push(actual_parameter_count);
SmiTag(actual.reg()); SmiUntag(actual_parameter_count);
Push(actual.reg());
SmiUntag(actual.reg());
}
if (new_target.is_valid()) { if (new_target.is_valid()) {
Push(new_target); Push(new_target);
} }
Push(fun); Push(fun);
Push(fun); Push(fun);
Operand receiver_op = Operand receiver_op =
actual.is_reg() Operand(ebp, actual_parameter_count, times_system_pointer_size,
? Operand(ebp, actual.reg(), times_system_pointer_size, kSystemPointerSize * 2);
kSystemPointerSize * 2)
: Operand(ebp, actual.immediate() * times_system_pointer_size +
kSystemPointerSize * 2);
Push(receiver_op); Push(receiver_op);
CallRuntime(Runtime::kDebugOnFunctionCall); CallRuntime(Runtime::kDebugOnFunctionCall);
Pop(fun); Pop(fun);
if (new_target.is_valid()) { if (new_target.is_valid()) {
Pop(new_target); Pop(new_target);
} }
if (actual.is_reg()) { Pop(actual_parameter_count);
Pop(actual.reg()); SmiUntag(actual_parameter_count);
SmiUntag(actual.reg());
} Pop(expected_parameter_count);
if (expected.is_reg()) { SmiUntag(expected_parameter_count);
Pop(expected.reg());
SmiUntag(expected.reg());
}
} }
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(flag == JUMP_FUNCTION || has_frame());
DCHECK(function == edi); DCHECK_EQ(function, edi);
DCHECK_IMPLIES(new_target.is_valid(), new_target == edx); DCHECK_IMPLIES(new_target.is_valid(), new_target == edx);
DCHECK_IMPLIES(expected.is_reg(), expected.reg() == ecx); DCHECK(expected_parameter_count == ecx || expected_parameter_count == eax);
DCHECK_IMPLIES(actual.is_reg(), actual.reg() == eax); DCHECK_EQ(actual_parameter_count, eax);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
Label debug_hook, continue_after_hook; Label debug_hook, continue_after_hook;
...@@ -1238,34 +1187,31 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -1238,34 +1187,31 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
} }
Label done; Label done;
bool definitely_mismatches = false; InvokePrologue(expected_parameter_count, actual_parameter_count, &done, flag);
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, // We call indirectly through the code field in the function to
Label::kNear); // allow recompilation to take effect without changing any of the
if (!definitely_mismatches) { // call sites.
// We call indirectly through the code field in the function to static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch");
// allow recompilation to take effect without changing any of the mov(ecx, FieldOperand(function, JSFunction::kCodeOffset));
// call sites. if (flag == CALL_FUNCTION) {
static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch"); CallCodeObject(ecx);
mov(ecx, FieldOperand(function, JSFunction::kCodeOffset)); } else {
if (flag == CALL_FUNCTION) { DCHECK(flag == JUMP_FUNCTION);
CallCodeObject(ecx); JumpCodeObject(ecx);
} else {
DCHECK(flag == JUMP_FUNCTION);
JumpCodeObject(ecx);
}
} }
jmp(&done, Label::kNear); jmp(&done, Label::kNear);
// Deferred debug hook. // Deferred debug hook.
bind(&debug_hook); bind(&debug_hook);
CallDebugOnFunctionCall(function, new_target, expected, actual); CallDebugOnFunctionCall(function, new_target, expected_parameter_count,
actual_parameter_count);
jmp(&continue_after_hook, Label::kNear); jmp(&continue_after_hook, Label::kNear);
bind(&done); bind(&done);
} }
void MacroAssembler::InvokeFunction(Register fun, Register new_target, void MacroAssembler::InvokeFunction(Register fun, Register new_target,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(flag == JUMP_FUNCTION || has_frame());
...@@ -1276,8 +1222,7 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target, ...@@ -1276,8 +1222,7 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target,
movzx_w(ecx, movzx_w(ecx,
FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount expected(ecx); InvokeFunctionCode(edi, new_target, ecx, actual_parameter_count, flag);
InvokeFunctionCode(edi, new_target, expected, actual, flag);
} }
void MacroAssembler::LoadGlobalProxy(Register dst) { void MacroAssembler::LoadGlobalProxy(Register dst) {
......
...@@ -565,19 +565,19 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -565,19 +565,19 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Invoke the JavaScript function code by either calling or jumping. // Invoke the JavaScript function code by either calling or jumping.
void InvokeFunctionCode(Register function, Register new_target, void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// On function call, call into the debugger. // On function call, call into the debugger.
// This may clobber ecx. // This may clobber ecx.
void CallDebugOnFunctionCall(Register fun, Register new_target, void CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual); Register actual_parameter_count);
// Invoke the JavaScript function in the given register. Changes the // Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking. // current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target, void InvokeFunction(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// Compare object type for heap object. // Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map. // Incoming register is heap_object and outgoing register is map.
...@@ -707,10 +707,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -707,10 +707,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
private: private:
// Helper functions for generating invokes. // Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected, void InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count, Label* done,
bool* definitely_mismatches, InvokeFlag flag, InvokeFlag flag);
Label::Distance done_distance);
void EnterExitFramePrologue(StackFrame::Type frame_type, Register scratch); void EnterExitFramePrologue(StackFrame::Type frame_type, Register scratch);
void EnterExitFrameEpilogue(int argc, bool save_doubles); void EnterExitFrameEpilogue(int argc, bool save_doubles);
......
...@@ -2351,30 +2351,30 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, ...@@ -2351,30 +2351,30 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
} }
void MacroAssembler::InvokeFunction(Register function, Register new_target, void MacroAssembler::InvokeFunction(Register function, Register new_target,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
LoadTaggedPointerField( LoadTaggedPointerField(
rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
movzxwq(rbx, movzxwq(rbx,
FieldOperand(rbx, SharedFunctionInfo::kFormalParameterCountOffset)); FieldOperand(rbx, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount expected(rbx); InvokeFunction(function, new_target, rbx, actual_parameter_count, flag);
InvokeFunction(function, new_target, expected, actual, flag);
} }
void MacroAssembler::InvokeFunction(Register function, Register new_target, void MacroAssembler::InvokeFunction(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
DCHECK(function == rdi); DCHECK(function == rdi);
LoadTaggedPointerField(rsi, LoadTaggedPointerField(rsi,
FieldOperand(function, JSFunction::kContextOffset)); FieldOperand(function, JSFunction::kContextOffset));
InvokeFunctionCode(rdi, new_target, expected, actual, flag); InvokeFunctionCode(rdi, new_target, expected_parameter_count,
actual_parameter_count, flag);
} }
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, Register actual_parameter_count,
InvokeFlag flag) { InvokeFlag flag) {
// You can't call a function without a valid frame. // You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(flag == JUMP_FUNCTION || has_frame());
...@@ -2399,127 +2399,81 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -2399,127 +2399,81 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
} }
Label done; Label done;
bool definitely_mismatches = false; InvokePrologue(expected_parameter_count, actual_parameter_count, &done, flag);
InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, // We call indirectly through the code field in the function to
Label::kNear); // allow recompilation to take effect without changing any of the
if (!definitely_mismatches) { // call sites.
// We call indirectly through the code field in the function to static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch");
// allow recompilation to take effect without changing any of the LoadTaggedPointerField(rcx, FieldOperand(function, JSFunction::kCodeOffset));
// call sites. if (flag == CALL_FUNCTION) {
static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch"); CallCodeObject(rcx);
LoadTaggedPointerField(rcx, } else {
FieldOperand(function, JSFunction::kCodeOffset)); DCHECK(flag == JUMP_FUNCTION);
if (flag == CALL_FUNCTION) { JumpCodeObject(rcx);
CallCodeObject(rcx);
} else {
DCHECK(flag == JUMP_FUNCTION);
JumpCodeObject(rcx);
}
} }
jmp(&done, Label::kNear); jmp(&done, Label::kNear);
// Deferred debug hook. // Deferred debug hook.
bind(&debug_hook); bind(&debug_hook);
CallDebugOnFunctionCall(function, new_target, expected, actual); CallDebugOnFunctionCall(function, new_target, expected_parameter_count,
actual_parameter_count);
jmp(&continue_after_hook, Label::kNear); jmp(&continue_after_hook, Label::kNear);
bind(&done); bind(&done);
} }
void MacroAssembler::InvokePrologue(const ParameterCount& expected, void MacroAssembler::InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count,
bool* definitely_mismatches, Label* done, InvokeFlag flag) {
InvokeFlag flag, if (expected_parameter_count != actual_parameter_count) {
Label::Distance near_jump) { Label regular_invoke;
bool definitely_matches = false; // Both expected and actual are in (different) registers. This
*definitely_mismatches = false; // is the case when we invoke functions using call and apply.
Label invoke; cmpq(expected_parameter_count, actual_parameter_count);
if (expected.is_immediate()) { j(equal, &regular_invoke, Label::kNear);
DCHECK(actual.is_immediate()); DCHECK_EQ(actual_parameter_count, rax);
Set(rax, actual.immediate()); DCHECK_EQ(expected_parameter_count, rbx);
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
if (expected.immediate() ==
SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
// Don't worry about adapting arguments for built-ins 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;
Set(rbx, expected.immediate());
}
}
} else {
if (actual.is_immediate()) {
// Expected is in register, actual is immediate. This is the
// case when we invoke function values without going through the
// IC mechanism.
Set(rax, actual.immediate());
cmpq(expected.reg(), Immediate(actual.immediate()));
j(equal, &invoke, Label::kNear);
DCHECK(expected.reg() == rbx);
} else if (expected.reg() != actual.reg()) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
cmpq(expected.reg(), actual.reg());
j(equal, &invoke, Label::kNear);
DCHECK(actual.reg() == rax);
DCHECK(expected.reg() == rbx);
} else {
definitely_matches = true;
Move(rax, actual.reg());
}
}
if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline); Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
if (flag == CALL_FUNCTION) { if (flag == CALL_FUNCTION) {
Call(adaptor, RelocInfo::CODE_TARGET); Call(adaptor, RelocInfo::CODE_TARGET);
if (!*definitely_mismatches) { jmp(done, Label::kNear);
jmp(done, near_jump);
}
} else { } else {
Jump(adaptor, RelocInfo::CODE_TARGET); Jump(adaptor, RelocInfo::CODE_TARGET);
} }
bind(&invoke); bind(&regular_invoke);
} else {
Move(rax, actual_parameter_count);
} }
} }
void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual) { Register actual_parameter_count) {
FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
if (expected.is_reg()) {
SmiTag(expected.reg()); SmiTag(expected_parameter_count);
Push(expected.reg()); Push(expected_parameter_count);
}
if (actual.is_reg()) { SmiTag(actual_parameter_count);
SmiTag(actual.reg()); Push(actual_parameter_count);
Push(actual.reg()); SmiUntag(actual_parameter_count);
SmiUntag(actual.reg());
}
if (new_target.is_valid()) { if (new_target.is_valid()) {
Push(new_target); Push(new_target);
} }
Push(fun); Push(fun);
Push(fun); Push(fun);
Push(StackArgumentsAccessor(rbp, actual).GetReceiverOperand()); Push(
StackArgumentsAccessor(rbp, actual_parameter_count).GetReceiverOperand());
CallRuntime(Runtime::kDebugOnFunctionCall); CallRuntime(Runtime::kDebugOnFunctionCall);
Pop(fun); Pop(fun);
if (new_target.is_valid()) { if (new_target.is_valid()) {
Pop(new_target); Pop(new_target);
} }
if (actual.is_reg()) { Pop(actual_parameter_count);
Pop(actual.reg()); SmiUntag(actual_parameter_count);
SmiUntag(actual.reg()); Pop(expected_parameter_count);
} SmiUntag(expected_parameter_count);
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
} }
void TurboAssembler::StubPrologue(StackFrame::Type type) { void TurboAssembler::StubPrologue(StackFrame::Type type) {
......
...@@ -705,22 +705,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -705,22 +705,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Invoke the JavaScript function code by either calling or jumping. // Invoke the JavaScript function code by either calling or jumping.
void InvokeFunctionCode(Register function, Register new_target, void InvokeFunctionCode(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// On function call, call into the debugger. // On function call, call into the debugger.
void CallDebugOnFunctionCall(Register fun, Register new_target, void CallDebugOnFunctionCall(Register fun, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual); Register actual_parameter_count);
// Invoke the JavaScript function in the given register. Changes the // Invoke the JavaScript function in the given register. Changes the
// current context to the context in the function before invoking. // current context to the context in the function before invoking.
void InvokeFunction(Register function, Register new_target, void InvokeFunction(Register function, Register new_target,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
void InvokeFunction(Register function, Register new_target, void InvokeFunction(Register function, Register new_target,
const ParameterCount& expected, Register expected_parameter_count,
const ParameterCount& actual, InvokeFlag flag); Register actual_parameter_count, InvokeFlag flag);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Conversions between tagged smi values and non-tagged integer values. // Conversions between tagged smi values and non-tagged integer values.
...@@ -926,10 +926,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -926,10 +926,9 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
static const int kNumSafepointSavedRegisters = 12; static const int kNumSafepointSavedRegisters = 12;
// Helper functions for generating invokes. // Helper functions for generating invokes.
void InvokePrologue(const ParameterCount& expected, void InvokePrologue(Register expected_parameter_count,
const ParameterCount& actual, Label* done, Register actual_parameter_count, Label* done,
bool* definitely_mismatches, InvokeFlag flag, InvokeFlag flag);
Label::Distance near_jump);
void EnterExitFramePrologue(bool save_rax, StackFrame::Type frame_type); void EnterExitFramePrologue(bool save_rax, StackFrame::Type frame_type);
......
...@@ -44,9 +44,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -44,9 +44,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
FieldMemOperand(r0, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(r0, SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(r2, r0); __ mov(r2, r0);
ParameterCount dummy1(r2); __ InvokeFunction(r1, r2, r0, JUMP_FUNCTION);
ParameterCount dummy2(r0);
__ InvokeFunction(r1, dummy1, dummy2, JUMP_FUNCTION);
} }
......
...@@ -44,11 +44,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -44,11 +44,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldrh(x0, __ Ldrh(x0,
FieldMemOperand(x0, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(x0, SharedFunctionInfo::kFormalParameterCountOffset));
__ mov(x2, x0); __ mov(x3, x0);
ParameterCount dummy1(x2); __ InvokeFunctionWithNewTarget(x1, x3, x0, JUMP_FUNCTION);
ParameterCount dummy2(x0);
__ InvokeFunction(x1, dummy1, dummy2, JUMP_FUNCTION);
} }
......
...@@ -42,9 +42,8 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -42,9 +42,8 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
// The expected and actual argument counts don't matter as long as they match // The expected and actual argument counts don't matter as long as they match
// and we don't enter the ArgumentsAdaptorTrampoline. // and we don't enter the ArgumentsAdaptorTrampoline.
ParameterCount dummy(0);
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
__ InvokeFunctionCode(edi, no_reg, dummy, dummy, JUMP_FUNCTION); __ InvokeFunctionCode(edi, no_reg, eax, eax, JUMP_FUNCTION);
} }
const bool LiveEdit::kFrameDropperSupported = true; const bool LiveEdit::kFrameDropperSupported = true;
......
...@@ -44,8 +44,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -44,8 +44,7 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
__ movzxwq( __ movzxwq(
rbx, FieldOperand(rbx, SharedFunctionInfo::kFormalParameterCountOffset)); rbx, FieldOperand(rbx, SharedFunctionInfo::kFormalParameterCountOffset));
ParameterCount dummy(rbx); __ InvokeFunction(rdi, no_reg, rbx, rbx, JUMP_FUNCTION);
__ InvokeFunction(rdi, no_reg, dummy, dummy, JUMP_FUNCTION);
} }
const bool LiveEdit::kFrameDropperSupported = true; const bool LiveEdit::kFrameDropperSupported = true;
......
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