From 1d1557d8fded51c323e01b4ca5e36be2861bee3b Mon Sep 17 00:00:00 2001 From: mbrandy Date: Mon, 23 Nov 2015 07:32:04 -0800 Subject: [PATCH] PPC: [turbofan]: Implement tail calls with more callee than caller parameters Port c6d310da4d86ce2d8178a49f4d34b66ad6143432 Original commit message: * Adds a PrepareForTailCall instruction that bumps the stack in the case that the number of parameters passed to the callee causes the stack to exceed the calleer's frame size. * Uses the gap resolver to move the saved caller return address and frame pointer to the approprate location in the tail-called frame. R=danno@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com BUG=v8:4076 LOG=n Review URL: https://codereview.chromium.org/1460183003 Cr-Commit-Position: refs/heads/master@{#32183} --- src/compiler/ppc/code-generator-ppc.cc | 31 ++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc index 3d199a68cc..6d8fd92435 100644 --- a/src/compiler/ppc/code-generator-ppc.cc +++ b/src/compiler/ppc/code-generator-ppc.cc @@ -606,14 +606,28 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { + int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); + if (sp_slot_delta > 0) { + __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); + } CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); - int stack_slots = frame()->GetSpillSlotCount(); - int sp_delta = - (stack_param_delta < 0) ? -stack_param_delta * kPointerSize : 0; - if (descriptor->IsJSFunctionCall() || stack_slots > 0) { - __ LeaveFrame(StackFrame::MANUAL, sp_delta); - } else if (sp_delta) { - __ Add(sp, sp, sp_delta, r0); + int spill_slots = frame()->GetSpillSlotCount(); + bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; + if (has_frame) { + if (FLAG_enable_embedded_constant_pool) { + __ Pop(r0, fp, kConstantPoolRegister); + } else { + __ Pop(r0, fp); + } + __ mtlr(r0); + } +} + + +void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { + int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); + if (sp_slot_delta < 0) { + __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); } } @@ -703,6 +717,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ PrepareCallCFunction(num_parameters, kScratchReg); break; } + case kArchPrepareTailCall: + AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); + break; case kArchCallCFunction: { int const num_parameters = MiscField::decode(instr->opcode()); if (instr->InputAt(0)->IsImmediate()) {