Commit d93dab6b authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

Revert "PPC/s390: [codegen] Removed ParameterCount class"

This reverts commit 2da05dfc.

Reason for revert: Will need to commit some of the changes as a port of  46648402

Original change's description:
> PPC/s390: [codegen] Removed ParameterCount class
> 
> Port 1e696896
> 
> Original Commit Message:
> 
>     It was used only with Register inputs, so we can replace its uses with
>     the Registers themselves.
> 
> R=​solanes@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
> BUG=
> LOG=N
> 
> Change-Id: I95c0e6fc19ea5f9579d022756a4693ea0140d2f7
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1890543
> Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
> Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
> Cr-Commit-Position: refs/heads/master@{#64661}

TBR=michael_dawson@ca.ibm.com,jyan@ca.ibm.com,joransiu@ca.ibm.com,miladfar@ca.ibm.com,solanes@chromium.org

Change-Id: I10f0a7f3c81f7c5c396df1e26ead50c5f8755231
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1891073Reviewed-by: 's avatarMilad Farazmand <miladfar@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#64662}
parent 2da05dfc
...@@ -144,7 +144,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -144,7 +144,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// r6: new target // r6: new target
{ {
ConstantPoolUnavailableScope constant_pool_unavailable(masm); ConstantPoolUnavailableScope constant_pool_unavailable(masm);
__ InvokeFunction(r4, r6, r3, CALL_FUNCTION); ParameterCount actual(r3);
__ InvokeFunction(r4, r6, actual, CALL_FUNCTION);
} }
// Restore context from the frame. // Restore context from the frame.
...@@ -299,7 +300,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -299,7 +300,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// Call the function. // Call the function.
{ {
ConstantPoolUnavailableScope constant_pool_unavailable(masm); ConstantPoolUnavailableScope constant_pool_unavailable(masm);
__ InvokeFunction(r4, r6, r3, CALL_FUNCTION); ParameterCount actual(r3);
__ InvokeFunction(r4, r6, actual, CALL_FUNCTION);
} }
// ----------- S t a t e ------------- // ----------- S t a t e -------------
...@@ -2100,7 +2102,9 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2100,7 +2102,9 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ LoadHalfWord( __ LoadHalfWord(
r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset)); r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset));
__ InvokeFunctionCode(r4, no_reg, r5, r3, JUMP_FUNCTION); ParameterCount actual(r3);
ParameterCount expected(r5);
__ InvokeFunctionCode(r4, 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);
......
...@@ -139,7 +139,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { ...@@ -139,7 +139,8 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// r3: constructor function // r3: constructor function
// r5: new target // r5: new target
__ InvokeFunction(r3, r5, r2, CALL_FUNCTION); ParameterCount actual(r2);
__ InvokeFunction(r3, r5, actual, CALL_FUNCTION);
// Restore context from the frame. // Restore context from the frame.
__ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
...@@ -292,7 +293,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { ...@@ -292,7 +293,8 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ bind(&no_args); __ bind(&no_args);
// Call the function. // Call the function.
__ InvokeFunction(r3, r5, r2, CALL_FUNCTION); ParameterCount actual(r2);
__ InvokeFunction(r3, r5, actual, CALL_FUNCTION);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r0: constructor result // -- r0: constructor result
...@@ -2158,7 +2160,9 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2158,7 +2160,9 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ LoadLogicalHalfWordP( __ LoadLogicalHalfWordP(
r4, FieldMemOperand(r4, SharedFunctionInfo::kFormalParameterCountOffset)); r4, FieldMemOperand(r4, SharedFunctionInfo::kFormalParameterCountOffset));
__ InvokeFunctionCode(r3, no_reg, r4, r2, JUMP_FUNCTION); ParameterCount actual(r2);
ParameterCount expected(r4);
__ InvokeFunctionCode(r3, 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);
......
...@@ -1152,25 +1152,36 @@ void TurboAssembler::MovFromFloatParameter(const DoubleRegister dst) { ...@@ -1152,25 +1152,36 @@ void TurboAssembler::MovFromFloatParameter(const DoubleRegister dst) {
Move(dst, d1); Move(dst, d1);
} }
void TurboAssembler::PrepareForTailCall(Register callee_args_count, void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count, Register caller_args_count_reg,
Register scratch0, Register scratch1) { Register scratch0, Register scratch1) {
DCHECK(!AreAliased(callee_args_count, caller_args_count, scratch0, 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 // Calculate the end of destination area where we will put the arguments
// after we drop current frame. We add kPointerSize to count the receiver // after we drop current frame. We add kPointerSize to count the receiver
// argument which is not included into formal parameters count. // argument which is not included into formal parameters count.
Register dst_reg = scratch0; Register dst_reg = scratch0;
ShiftLeftImm(dst_reg, caller_args_count, Operand(kPointerSizeLog2)); ShiftLeftImm(dst_reg, caller_args_count_reg, Operand(kPointerSizeLog2));
add(dst_reg, fp, dst_reg); add(dst_reg, fp, dst_reg);
addi(dst_reg, dst_reg, addi(dst_reg, dst_reg,
Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize)); Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
Register src_reg = caller_args_count; Register src_reg = caller_args_count_reg;
// Calculate the end of source area. +kPointerSize is for the receiver. // Calculate the end of source area. +kPointerSize is for the receiver.
ShiftLeftImm(src_reg, callee_args_count, Operand(kPointerSizeLog2)); if (callee_args_count.is_reg()) {
add(src_reg, sp, src_reg); ShiftLeftImm(src_reg, callee_args_count.reg(), Operand(kPointerSizeLog2));
addi(src_reg, src_reg, Operand(kPointerSize)); add(src_reg, sp, src_reg);
addi(src_reg, src_reg, Operand(kPointerSize));
} else {
Add(src_reg, sp, (callee_args_count.immediate() + 1) * kPointerSize, r0);
}
if (FLAG_debug_code) { if (FLAG_debug_code) {
cmpl(src_reg, dst_reg); cmpl(src_reg, dst_reg);
...@@ -1188,7 +1199,11 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count, ...@@ -1188,7 +1199,11 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
// so they must be pre-decremented in the loop. // so they must be pre-decremented in the loop.
Register tmp_reg = scratch1; Register tmp_reg = scratch1;
Label loop; Label loop;
addi(tmp_reg, callee_args_count, Operand(1)); // +1 for receiver if (callee_args_count.is_reg()) {
addi(tmp_reg, callee_args_count.reg(), Operand(1)); // +1 for receiver
} else {
mov(tmp_reg, Operand(callee_args_count.immediate() + 1));
}
mtctr(tmp_reg); mtctr(tmp_reg);
bind(&loop); bind(&loop);
LoadPU(tmp_reg, MemOperand(src_reg, -kPointerSize)); LoadPU(tmp_reg, MemOperand(src_reg, -kPointerSize));
...@@ -1199,8 +1214,9 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count, ...@@ -1199,8 +1214,9 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
mr(sp, dst_reg); mr(sp, dst_reg);
} }
void MacroAssembler::InvokePrologue(Register expected, Register actual, void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Label* done, bool* definitely_mismatches, const ParameterCount& actual, Label* done,
bool* definitely_mismatches,
InvokeFlag flag) { InvokeFlag flag) {
bool definitely_matches = false; bool definitely_matches = false;
*definitely_mismatches = false; *definitely_mismatches = false;
...@@ -1220,8 +1236,34 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual, ...@@ -1220,8 +1236,34 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual,
// DCHECK(actual.is_immediate() || actual.reg() == r3); // DCHECK(actual.is_immediate() || actual.reg() == r3);
// DCHECK(expected.is_immediate() || expected.reg() == r5); // DCHECK(expected.is_immediate() || expected.reg() == r5);
cmp(expected, actual); if (expected.is_immediate()) {
beq(&regular_invoke); DCHECK(actual.is_immediate());
mov(r3, 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;
mov(r5, Operand(expected.immediate()));
}
}
} else {
if (actual.is_immediate()) {
mov(r3, Operand(actual.immediate()));
cmpi(expected.reg(), Operand(actual.immediate()));
beq(&regular_invoke);
} else {
cmp(expected.reg(), actual.reg());
beq(&regular_invoke);
}
}
if (!definitely_matches) { if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline); Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
...@@ -1238,7 +1280,8 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual, ...@@ -1238,7 +1280,8 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual,
} }
void MacroAssembler::CheckDebugHook(Register fun, Register new_target, void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
Register expected, Register actual) { const ParameterCount& expected,
const ParameterCount& actual) {
Label skip_hook; Label skip_hook;
ExternalReference debug_hook_active = ExternalReference debug_hook_active =
...@@ -1251,14 +1294,22 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, ...@@ -1251,14 +1294,22 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
{ {
// Load receiver to pass it later to DebugOnFunctionCall hook. // Load receiver to pass it later to DebugOnFunctionCall hook.
ShiftLeftImm(r7, actual, Operand(kPointerSizeLog2)); if (actual.is_reg()) {
LoadPX(r7, MemOperand(sp, r7)); ShiftLeftImm(r7, actual.reg(), Operand(kPointerSizeLog2));
LoadPX(r7, MemOperand(sp, r7));
} else {
LoadP(r7, MemOperand(sp, actual.immediate() << kPointerSizeLog2), r0);
}
FrameScope frame(this, FrameScope frame(this,
has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
SmiTag(expected); if (expected.is_reg()) {
Push(expected); SmiTag(expected.reg());
SmiTag(actual); Push(expected.reg());
Push(actual); }
if (actual.is_reg()) {
SmiTag(actual.reg());
Push(actual.reg());
}
if (new_target.is_valid()) { if (new_target.is_valid()) {
Push(new_target); Push(new_target);
} }
...@@ -1268,20 +1319,26 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, ...@@ -1268,20 +1319,26 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
if (new_target.is_valid()) { if (new_target.is_valid()) {
Pop(new_target); Pop(new_target);
} }
Pop(actual); if (actual.is_reg()) {
SmiUntag(actual); Pop(actual.reg());
Pop(expected); SmiUntag(actual.reg());
SmiUntag(expected); }
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
} }
bind(&skip_hook); bind(&skip_hook);
} }
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
Register expected, Register actual, const ParameterCount& expected,
const ParameterCount& actual,
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 == r4); DCHECK(function == r4);
DCHECK_IMPLIES(new_target.is_valid(), new_target == r6);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
CheckDebugHook(function, new_target, expected, actual); CheckDebugHook(function, new_target, expected, actual);
...@@ -1314,7 +1371,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -1314,7 +1371,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
} }
void MacroAssembler::InvokeFunction(Register fun, Register new_target, void MacroAssembler::InvokeFunction(Register fun, Register new_target,
Register actual, InvokeFlag flag) { const ParameterCount& actual,
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());
...@@ -1330,7 +1388,24 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target, ...@@ -1330,7 +1388,24 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target,
FieldMemOperand( FieldMemOperand(
temp_reg, SharedFunctionInfo::kFormalParameterCountOffset)); temp_reg, SharedFunctionInfo::kFormalParameterCountOffset));
InvokeFunctionCode(fun, new_target, expected_reg, actual, flag); ParameterCount expected(expected_reg);
InvokeFunctionCode(fun, new_target, expected, actual, flag);
}
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
// Contract with called JS functions requires that function is passed in r4.
DCHECK(function == r4);
// Get the function and setup the context.
LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
InvokeFunctionCode(r4, no_reg, expected, actual, flag);
} }
void MacroAssembler::MaybeDropFrames() { void MacroAssembler::MaybeDropFrames() {
......
...@@ -333,8 +333,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -333,8 +333,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
Register scratch); Register scratch);
void PrepareCallCFunction(int num_reg_arguments, Register scratch); void PrepareCallCFunction(int num_reg_arguments, Register scratch);
void PrepareForTailCall(Register callee_args_count, void PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count, Register scratch0, Register caller_args_count_reg, Register scratch0,
Register scratch1); Register scratch1);
// There are two ways of passing double arguments on ARM, depending on // There are two ways of passing double arguments on ARM, depending on
...@@ -743,22 +743,27 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -743,22 +743,27 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Removes current frame and its arguments from the stack preserving // Removes current frame and its arguments from the stack preserving
// the arguments and a return address pushed to the stack for the next call. // the arguments and a return address pushed to the stack for the next call.
// Both |callee_args_count| and |caller_args_count| do not include // Both |callee_args_count| and |caller_args_count_reg| do not include
// receiver. |callee_args_count| is not modified. |caller_args_count| // receiver. |callee_args_count| is not modified, |caller_args_count_reg|
// is trashed. // is trashed.
// 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,
Register expected, Register actual, InvokeFlag flag); const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
void CheckDebugHook(Register fun, Register new_target, Register expected, void CheckDebugHook(Register fun, Register new_target,
Register actual); const ParameterCount& expected,
const ParameterCount& actual);
// 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, Register actual, void InvokeFunction(Register function, Register new_target,
InvokeFlag flag); const ParameterCount& actual, InvokeFlag flag);
void InvokeFunction(Register function, const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
void DebugBreak(); void DebugBreak();
// Frame restart support // Frame restart support
...@@ -945,7 +950,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -945,7 +950,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
static const int kSmiShift = kSmiTagSize + kSmiShiftSize; static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
// Helper functions for generating invokes. // Helper functions for generating invokes.
void InvokePrologue(Register expected, Register actual, Label* done, void InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches, InvokeFlag flag); bool* definitely_mismatches, InvokeFlag flag);
// Compute memory operands for safepoint stack slots. // Compute memory operands for safepoint stack slots.
......
...@@ -1201,25 +1201,39 @@ void TurboAssembler::MovFromFloatParameter(const DoubleRegister dst) { ...@@ -1201,25 +1201,39 @@ void TurboAssembler::MovFromFloatParameter(const DoubleRegister dst) {
Move(dst, d0); Move(dst, d0);
} }
void TurboAssembler::PrepareForTailCall(Register callee_args_count, void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count, Register caller_args_count_reg,
Register scratch0, Register scratch1) { Register scratch0, Register scratch1) {
DCHECK(!AreAliased(callee_args_count, caller_args_count, scratch0, 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 // Calculate the end of destination area where we will put the arguments
// after we drop current frame. We AddP kSystemPointerSize to count the // after we drop current frame. We AddP kSystemPointerSize to count the
// receiver argument which is not included into formal parameters count. // receiver argument which is not included into formal parameters count.
Register dst_reg = scratch0; Register dst_reg = scratch0;
ShiftLeftP(dst_reg, caller_args_count, Operand(kSystemPointerSizeLog2)); ShiftLeftP(dst_reg, caller_args_count_reg, Operand(kSystemPointerSizeLog2));
AddP(dst_reg, fp, dst_reg); AddP(dst_reg, fp, dst_reg);
AddP(dst_reg, dst_reg, AddP(dst_reg, dst_reg,
Operand(StandardFrameConstants::kCallerSPOffset + kSystemPointerSize)); Operand(StandardFrameConstants::kCallerSPOffset + kSystemPointerSize));
Register src_reg = caller_args_count; Register src_reg = caller_args_count_reg;
// Calculate the end of source area. +kSystemPointerSize is for the receiver. // Calculate the end of source area. +kSystemPointerSize is for the receiver.
ShiftLeftP(src_reg, callee_args_count, Operand(kSystemPointerSizeLog2)); if (callee_args_count.is_reg()) {
AddP(src_reg, sp, src_reg); ShiftLeftP(src_reg, callee_args_count.reg(),
AddP(src_reg, src_reg, Operand(kSystemPointerSize)); Operand(kSystemPointerSizeLog2));
AddP(src_reg, sp, src_reg);
AddP(src_reg, src_reg, Operand(kSystemPointerSize));
} else {
mov(src_reg,
Operand((callee_args_count.immediate() + 1) * kSystemPointerSize));
AddP(src_reg, src_reg, sp);
}
if (FLAG_debug_code) { if (FLAG_debug_code) {
CmpLogicalP(src_reg, dst_reg); CmpLogicalP(src_reg, dst_reg);
...@@ -1237,7 +1251,11 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count, ...@@ -1237,7 +1251,11 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
// so they must be pre-decremented in the loop. // so they must be pre-decremented in the loop.
Register tmp_reg = scratch1; Register tmp_reg = scratch1;
Label loop; Label loop;
AddP(tmp_reg, callee_args_count, Operand(1)); // +1 for receiver if (callee_args_count.is_reg()) {
AddP(tmp_reg, callee_args_count.reg(), Operand(1)); // +1 for receiver
} else {
mov(tmp_reg, Operand(callee_args_count.immediate() + 1));
}
LoadRR(r1, tmp_reg); LoadRR(r1, tmp_reg);
bind(&loop); bind(&loop);
LoadP(tmp_reg, MemOperand(src_reg, -kSystemPointerSize)); LoadP(tmp_reg, MemOperand(src_reg, -kSystemPointerSize));
...@@ -1250,8 +1268,9 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count, ...@@ -1250,8 +1268,9 @@ void TurboAssembler::PrepareForTailCall(Register callee_args_count,
LoadRR(sp, dst_reg); LoadRR(sp, dst_reg);
} }
void MacroAssembler::InvokePrologue(Register expected, Register actual, void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Label* done, bool* definitely_mismatches, const ParameterCount& actual, Label* done,
bool* definitely_mismatches,
InvokeFlag flag) { InvokeFlag flag) {
bool definitely_matches = false; bool definitely_matches = false;
*definitely_mismatches = false; *definitely_mismatches = false;
...@@ -1268,11 +1287,37 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual, ...@@ -1268,11 +1287,37 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual,
// passed in registers. // passed in registers.
// ARM has some sanity checks as per below, considering add them for S390 // ARM has some sanity checks as per below, considering add them for S390
DCHECK(actual == r2); DCHECK(actual.is_immediate() || actual.reg() == r2);
DCHECK(expected == r4); DCHECK(expected.is_immediate() || expected.reg() == r4);
CmpP(expected, actual); if (expected.is_immediate()) {
beq(&regular_invoke); DCHECK(actual.is_immediate());
mov(r2, 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;
mov(r4, Operand(expected.immediate()));
}
}
} else {
if (actual.is_immediate()) {
mov(r2, Operand(actual.immediate()));
CmpPH(expected.reg(), Operand(actual.immediate()));
beq(&regular_invoke);
} else {
CmpP(expected.reg(), actual.reg());
beq(&regular_invoke);
}
}
if (!definitely_matches) { if (!definitely_matches) {
Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline); Handle<Code> adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline);
...@@ -1289,7 +1334,8 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual, ...@@ -1289,7 +1334,8 @@ void MacroAssembler::InvokePrologue(Register expected, Register actual,
} }
void MacroAssembler::CheckDebugHook(Register fun, Register new_target, void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
Register expected, Register actual) { const ParameterCount& expected,
const ParameterCount& actual) {
Label skip_hook; Label skip_hook;
ExternalReference debug_hook_active = ExternalReference debug_hook_active =
...@@ -1300,14 +1346,23 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, ...@@ -1300,14 +1346,23 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
{ {
// Load receiver to pass it later to DebugOnFunctionCall hook. // Load receiver to pass it later to DebugOnFunctionCall hook.
ShiftLeftP(r6, actual, Operand(kSystemPointerSizeLog2)); if (actual.is_reg()) {
LoadP(r6, MemOperand(sp, r6)); ShiftLeftP(r6, actual.reg(), Operand(kSystemPointerSizeLog2));
LoadP(r6, MemOperand(sp, r6));
} else {
LoadP(r6, MemOperand(sp, actual.immediate() << kSystemPointerSizeLog2),
ip);
}
FrameScope frame(this, FrameScope frame(this,
has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
SmiTag(expected); if (expected.is_reg()) {
Push(expected); SmiTag(expected.reg());
SmiTag(actual); Push(expected.reg());
Push(actual); }
if (actual.is_reg()) {
SmiTag(actual.reg());
Push(actual.reg());
}
if (new_target.is_valid()) { if (new_target.is_valid()) {
Push(new_target); Push(new_target);
} }
...@@ -1317,21 +1372,27 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, ...@@ -1317,21 +1372,27 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target,
if (new_target.is_valid()) { if (new_target.is_valid()) {
Pop(new_target); Pop(new_target);
} }
Pop(actual); if (actual.is_reg()) {
SmiUntag(actual); Pop(actual.reg());
Pop(expected); SmiUntag(actual.reg());
SmiUntag(expected); }
if (expected.is_reg()) {
Pop(expected.reg());
SmiUntag(expected.reg());
}
} }
bind(&skip_hook); bind(&skip_hook);
} }
void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
Register expected, Register actual, const ParameterCount& expected,
const ParameterCount& actual,
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 == r3); DCHECK(function == r3);
DCHECK_IMPLIES(new_target.is_valid(), new_target == r5);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
CheckDebugHook(function, new_target, expected, actual); CheckDebugHook(function, new_target, expected, actual);
...@@ -1364,7 +1425,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, ...@@ -1364,7 +1425,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
} }
void MacroAssembler::InvokeFunction(Register fun, Register new_target, void MacroAssembler::InvokeFunction(Register fun, Register new_target,
Register actual, InvokeFlag flag) { const ParameterCount& actual,
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());
...@@ -1380,7 +1442,24 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target, ...@@ -1380,7 +1442,24 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target,
FieldMemOperand(temp_reg, FieldMemOperand(temp_reg,
SharedFunctionInfo::kFormalParameterCountOffset)); SharedFunctionInfo::kFormalParameterCountOffset));
InvokeFunctionCode(fun, new_target, expected_reg, actual, flag); ParameterCount expected(expected_reg);
InvokeFunctionCode(fun, new_target, expected, actual, flag);
}
void MacroAssembler::InvokeFunction(Register function,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag) {
// You can't call a function without a valid frame.
DCHECK(flag == JUMP_FUNCTION || has_frame());
// Contract with called JS functions requires that function is passed in r3.
DCHECK(function == r3);
// Get the function and setup the context.
LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
InvokeFunctionCode(r3, no_reg, expected, actual, flag);
} }
void MacroAssembler::MaybeDropFrames() { void MacroAssembler::MaybeDropFrames() {
......
...@@ -804,8 +804,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -804,8 +804,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
#endif #endif
} }
void PrepareForTailCall(Register callee_args_count, void PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count, Register scratch0, Register caller_args_count_reg, Register scratch0,
Register scratch1); Register scratch1);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -1119,22 +1119,27 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -1119,22 +1119,27 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Removes current frame and its arguments from the stack preserving // Removes current frame and its arguments from the stack preserving
// the arguments and a return address pushed to the stack for the next call. // the arguments and a return address pushed to the stack for the next call.
// Both |callee_args_count| and |caller_args_count| do not include // Both |callee_args_count| and |caller_args_count_reg| do not include
// receiver. |callee_args_count| is not modified. |caller_args_count| // receiver. |callee_args_count| is not modified, |caller_args_count_reg|
// is trashed. // is trashed.
// 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,
Register expected, Register actual, InvokeFlag flag); const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
// On function call, call into the debugger if necessary. // On function call, call into the debugger if necessary.
void CheckDebugHook(Register fun, Register new_target, Register expected, void CheckDebugHook(Register fun, Register new_target,
Register actual); const ParameterCount& expected,
const ParameterCount& actual);
// 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, Register actual, void InvokeFunction(Register function, Register new_target,
InvokeFlag flag); const ParameterCount& actual, InvokeFlag flag);
void InvokeFunction(Register function, const ParameterCount& expected,
const ParameterCount& actual, InvokeFlag flag);
// Frame restart support // Frame restart support
void MaybeDropFrames(); void MaybeDropFrames();
...@@ -1271,7 +1276,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -1271,7 +1276,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
private: private:
static const int kSmiShift = kSmiTagSize + kSmiShiftSize; static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
// Helper functions for generating invokes. // Helper functions for generating invokes.
void InvokePrologue(Register expected, Register actual, Label* done, void InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual, Label* done,
bool* definitely_mismatches, InvokeFlag flag); bool* definitely_mismatches, InvokeFlag flag);
// Compute memory operands for safepoint stack slots. // Compute memory operands for safepoint stack slots.
......
...@@ -704,7 +704,9 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, ...@@ -704,7 +704,9 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(caller_args_count_reg); __ SmiUntag(caller_args_count_reg);
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3); ParameterCount callee_args_count(args_reg);
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
scratch3);
__ bind(&done); __ bind(&done);
} }
......
...@@ -1193,7 +1193,9 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, ...@@ -1193,7 +1193,9 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiUntag(caller_args_count_reg); __ SmiUntag(caller_args_count_reg);
__ PrepareForTailCall(args_reg, caller_args_count_reg, scratch2, scratch3); ParameterCount callee_args_count(args_reg);
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
scratch3);
__ bind(&done); __ bind(&done);
} }
......
...@@ -41,7 +41,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -41,7 +41,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
__ mr(r5, r3); __ mr(r5, r3);
__ InvokeFunction(r4, r5, r3, JUMP_FUNCTION); ParameterCount dummy1(r5);
ParameterCount dummy2(r3);
__ InvokeFunction(r4, dummy1, dummy2, JUMP_FUNCTION);
} }
const bool LiveEdit::kFrameDropperSupported = true; const bool LiveEdit::kFrameDropperSupported = true;
......
...@@ -43,7 +43,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { ...@@ -43,7 +43,9 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) {
r2, FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); r2, FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
__ LoadRR(r4, r2); __ LoadRR(r4, r2);
__ InvokeFunction(r3, r4, r2, JUMP_FUNCTION); ParameterCount dummy1(r4);
ParameterCount dummy2(r2);
__ InvokeFunction(r3, dummy1, dummy2, 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