| Index: src/x64/code-stubs-x64.cc | 
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc | 
| index 03a5170bae744491a17a054054c3da2c98cf9461..da9ce220df1547f97304ed395837f12b078ed073 100644 | 
| --- a/src/x64/code-stubs-x64.cc | 
| +++ b/src/x64/code-stubs-x64.cc | 
| @@ -3582,24 +3582,47 @@ void StackCheckStub::Generate(MacroAssembler* masm) { | 
| } | 
|  | 
|  | 
| -void CallFunctionStub::FinishCode(Handle<Code> code) { | 
| -  code->set_has_function_cache(false); | 
| -} | 
| - | 
| - | 
| -void CallFunctionStub::Clear(Heap* heap, Address address) { | 
| -  UNREACHABLE(); | 
| -} | 
| +static void GenerateRecordCallTarget(MacroAssembler* masm) { | 
| +  // Cache the called function in a global property cell.  Cache states | 
| +  // are uninitialized, monomorphic (indicated by a JSFunction), and | 
| +  // megamorphic. | 
| +  // rbx : cache cell for call target | 
| +  // rdi : the function to call | 
| +  Isolate* isolate = masm->isolate(); | 
| +  Label initialize, done; | 
| + | 
| +  // Load the cache state into rcx. | 
| +  __ movq(rcx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 
| + | 
| +  // A monomorphic cache hit or an already megamorphic state: invoke the | 
| +  // function without changing the state. | 
| +  __ cmpq(rcx, rdi); | 
| +  __ j(equal, &done, Label::kNear); | 
| +  __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); | 
| +  __ j(equal, &done, Label::kNear); | 
| + | 
| +  // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 
| +  // megamorphic. | 
| +  __ Cmp(rcx, TypeFeedbackCells::UninitializedSentinel(isolate)); | 
| +  __ j(equal, &initialize, Label::kNear); | 
| +  // MegamorphicSentinel is an immortal immovable object (undefined) so no | 
| +  // write-barrier is needed. | 
| +  __ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), | 
| +          TypeFeedbackCells::MegamorphicSentinel(isolate)); | 
| +  __ jmp(&done, Label::kNear); | 
|  | 
| +  // An uninitialized cache is patched with the function. | 
| +  __ bind(&initialize); | 
| +  __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rdi); | 
| +  // No need for a write barrier here - cells are rescanned. | 
|  | 
| -Object* CallFunctionStub::GetCachedValue(Address address) { | 
| -  UNREACHABLE(); | 
| -  return NULL; | 
| +  __ bind(&done); | 
| } | 
|  | 
|  | 
| void CallFunctionStub::Generate(MacroAssembler* masm) { | 
| // rdi : the function to call | 
| +  // rbx : cache cell for call target | 
| Label slow, non_function; | 
|  | 
| // The receiver might implicitly be the global object. This is | 
| @@ -3678,6 +3701,49 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { | 
| } | 
|  | 
|  | 
| +void CallConstructStub::Generate(MacroAssembler* masm) { | 
| +  // rax : number of arguments | 
| +  // rbx : cache cell for call target | 
| +  // rdi : constructor function | 
| +  Label slow, non_function_call; | 
| + | 
| +  // Check that function is not a smi. | 
| +  __ JumpIfSmi(rdi, &non_function_call); | 
| +  // Check that function is a JSFunction. | 
| +  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 
| +  __ j(not_equal, &slow); | 
| + | 
| +  if (RecordCallTarget()) { | 
| +    GenerateRecordCallTarget(masm); | 
| +  } | 
| + | 
| +  // Jump to the function-specific construct stub. | 
| +  __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 
| +  __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kConstructStubOffset)); | 
| +  __ lea(rbx, FieldOperand(rbx, Code::kHeaderSize)); | 
| +  __ jmp(rbx); | 
| + | 
| +  // rdi: called object | 
| +  // rax: number of arguments | 
| +  // rcx: object map | 
| +  Label do_call; | 
| +  __ bind(&slow); | 
| +  __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); | 
| +  __ j(not_equal, &non_function_call); | 
| +  __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 
| +  __ jmp(&do_call); | 
| + | 
| +  __ bind(&non_function_call); | 
| +  __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 
| +  __ bind(&do_call); | 
| +  // Set expected number of arguments to zero (not changing rax). | 
| +  __ Set(rbx, 0); | 
| +  __ SetCallKind(rcx, CALL_AS_METHOD); | 
| +  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 
| +          RelocInfo::CODE_TARGET); | 
| +} | 
| + | 
| + | 
| bool CEntryStub::NeedsImmovableCode() { | 
| return false; | 
| } | 
|  |