| Index: src/compiler/x64/code-generator-x64.cc | 
| diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc | 
| index 510c0c6a0c78bf62e3cd7bffe3b62fc36870a89f..8addb36440c9c946c44c62ef5cb1891fab65e4ac 100644 | 
| --- a/src/compiler/x64/code-generator-x64.cc | 
| +++ b/src/compiler/x64/code-generator-x64.cc | 
| @@ -621,6 +621,30 @@ void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { | 
| frame_access_state()->SetFrameAccessToSP(); | 
| } | 
|  | 
| +void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, | 
| +                                                     Register scratch1, | 
| +                                                     Register scratch2, | 
| +                                                     Register scratch3) { | 
| +  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); | 
| +  Label done; | 
| + | 
| +  // Check if current frame is an arguments adaptor frame. | 
| +  __ Cmp(Operand(rbp, StandardFrameConstants::kContextOffset), | 
| +         Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
| +  __ j(not_equal, &done, Label::kNear); | 
| + | 
| +  // Load arguments count from current arguments adaptor frame (note, it | 
| +  // does not include receiver). | 
| +  Register caller_args_count_reg = scratch1; | 
| +  __ SmiToInteger32( | 
| +      caller_args_count_reg, | 
| +      Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| + | 
| +  ParameterCount callee_args_count(args_reg); | 
| +  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, | 
| +                        scratch3, ReturnAddressState::kOnStack); | 
| +  __ bind(&done); | 
| +} | 
|  | 
| // Assembles an instruction after register allocation, producing machine code. | 
| void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 
| @@ -641,6 +665,23 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 
| frame_access_state()->ClearSPDelta(); | 
| break; | 
| } | 
| +    case kArchTailCallCodeObjectFromJSFunction: { | 
| +      int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 
| +      AssembleDeconstructActivationRecord(stack_param_delta); | 
| +      AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, | 
| +                                       i.TempRegister(0), i.TempRegister(1), | 
| +                                       i.TempRegister(2)); | 
| +      if (HasImmediateInput(instr, 0)) { | 
| +        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 
| +        __ jmp(code, RelocInfo::CODE_TARGET); | 
| +      } else { | 
| +        Register reg = i.InputRegister(0); | 
| +        __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 
| +        __ jmp(reg); | 
| +      } | 
| +      frame_access_state()->ClearSPDelta(); | 
| +      break; | 
| +    } | 
| case kArchTailCallCodeObject: { | 
| int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 
| AssembleDeconstructActivationRecord(stack_param_delta); | 
| @@ -668,6 +709,22 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 
| RecordCallPosition(instr); | 
| break; | 
| } | 
| +    case kArchTailCallJSFunctionFromJSFunction: { | 
| +      Register func = i.InputRegister(0); | 
| +      if (FLAG_debug_code) { | 
| +        // Check the function's context matches the context argument. | 
| +        __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 
| +        __ Assert(equal, kWrongFunctionContext); | 
| +      } | 
| +      int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 
| +      AssembleDeconstructActivationRecord(stack_param_delta); | 
| +      AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, | 
| +                                       i.TempRegister(0), i.TempRegister(1), | 
| +                                       i.TempRegister(2)); | 
| +      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 
| +      frame_access_state()->ClearSPDelta(); | 
| +      break; | 
| +    } | 
| case kArchTailCallJSFunction: { | 
| Register func = i.InputRegister(0); | 
| if (FLAG_debug_code) { | 
|  |