X87: [turbofan]: Implement tail calls with more callee than caller parameters.

port c6d310da4d (r32151)

  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.

BUG=

Review URL: https://codereview.chromium.org/1472703002

Cr-Commit-Position: refs/heads/master@{#32162}
This commit is contained in:
zhengxing.li 2015-11-22 19:30:28 -08:00 committed by Commit bot
parent d23330d496
commit 8dda6ee726

View File

@ -331,18 +331,23 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
if (sp_slot_delta > 0) {
__ add(esp, Immediate(sp_slot_delta * kPointerSize));
}
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
int stack_slots = frame()->GetSpillSlotCount();
if (descriptor->IsJSFunctionCall() || stack_slots > 0) {
__ mov(esp, ebp);
int spill_slots = frame()->GetSpillSlotCount();
bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0;
if (has_frame) {
__ pop(ebp);
}
if (stack_param_delta < 0) {
int offset = -(stack_param_delta + 1) * kPointerSize;
__ pop(Operand(esp, offset));
if (offset != 0) {
__ add(esp, Immediate(offset));
}
}
void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
if (sp_slot_delta < 0) {
__ sub(esp, Immediate(-sp_slot_delta * kPointerSize));
}
}
@ -438,6 +443,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ PrepareCallCFunction(num_parameters, i.TempRegister(0));
break;
}
case kArchPrepareTailCall:
AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
break;
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
if (HasImmediateInput(instr, 0)) {