| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index 80aef0c4ffefa253069de6ac66473a4ac116b2a4..54063bbb1b7343ecd7695ff3649bae983844dd54 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -1300,6 +1300,64 @@ void MacroAssembler::MovFromFloatParameter(DwVfpRegister dst) {
|
| MovFromFloatResult(dst);
|
| }
|
|
|
| +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, sp, Operand(callee_args_count.reg(), LSL, kPointerSizeLog2));
|
| + add(src_reg, src_reg, Operand(kPointerSize));
|
| + } else {
|
| + add(src_reg, sp,
|
| + 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(sp, src_reg);
|
| + b(ne, &loop);
|
| +
|
| + // Leave current frame.
|
| + mov(sp, dst_reg);
|
| +}
|
|
|
| void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
| const ParameterCount& actual,
|
|
|