| Index: src/arm64/macro-assembler-arm64.cc
|
| diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc
|
| index 953c3fd7f2bf245e24fbe1ed9e0850d726bf9d07..c4a3a998506ccfebb46a1dc8ce08fb4dcbb0c088 100644
|
| --- a/src/arm64/macro-assembler-arm64.cc
|
| +++ b/src/arm64/macro-assembler-arm64.cc
|
| @@ -2330,6 +2330,66 @@ void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register type,
|
| B(ne, not_unique_name);
|
| }
|
|
|
| +void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| + Register caller_args_count_reg,
|
| + 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;
|
| + __ add(dst_reg, fp, Operand(caller_args_count_reg, LSL, kPointerSizeLog2));
|
| + __ add(dst_reg, dst_reg,
|
| + Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
|
| +
|
| + Register src_reg = caller_args_count_reg;
|
| + // Calculate the end of source area. +kPointerSize is for the receiver.
|
| + if (callee_args_count.is_reg()) {
|
| + add(src_reg, jssp, Operand(callee_args_count.reg(), LSL, kPointerSizeLog2));
|
| + add(src_reg, src_reg, Operand(kPointerSize));
|
| + } else {
|
| + add(src_reg, jssp,
|
| + Operand((callee_args_count.immediate() + 1) * kPointerSize));
|
| + }
|
| +
|
| + if (FLAG_debug_code) {
|
| + __ Cmp(src_reg, dst_reg);
|
| + __ Check(lo, kStackAccessBelowStackPointer);
|
| + }
|
| +
|
| + // Restore caller's frame pointer and return address now as they will be
|
| + // overwritten by the copying loop.
|
| + __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
|
| + __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
| +
|
| + // Now copy callee arguments to the caller frame going backwards to avoid
|
| + // callee arguments corruption (source and destination areas could overlap).
|
| +
|
| + // Both src_reg and dst_reg are pointing to the word after the one to copy,
|
| + // so they must be pre-decremented in the loop.
|
| + Register tmp_reg = scratch1;
|
| + Label loop, entry;
|
| + __ B(&entry);
|
| + __ bind(&loop);
|
| + __ Ldr(tmp_reg, MemOperand(src_reg, -kPointerSize, PreIndex));
|
| + __ Str(tmp_reg, MemOperand(dst_reg, -kPointerSize, PreIndex));
|
| + __ bind(&entry);
|
| + __ Cmp(jssp, src_reg);
|
| + __ B(ne, &loop);
|
| +
|
| + // Leave current frame.
|
| + __ Mov(jssp, dst_reg);
|
| + __ SetStackPointer(jssp);
|
| + __ AssertStackConsistency();
|
| +}
|
|
|
| void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| const ParameterCount& actual,
|
|
|