| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 01bddaf970fc5ea384a5b444d60f05188eac06ae..a62a5a409d0ccf968699d192d02c4e94b80291a3 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -2087,6 +2087,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
| // rdi - function
|
| // rdx - slot id
|
| Isolate* isolate = masm->isolate();
|
| + const int with_types_offset =
|
| + FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
|
| + const int generic_offset =
|
| + FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
|
| Label extra_checks_or_miss, slow_start;
|
| Label slow, non_function, wrap, cont;
|
| Label have_js_function;
|
| @@ -2128,34 +2132,64 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
| }
|
|
|
| __ bind(&extra_checks_or_miss);
|
| - Label miss;
|
| + Label uninitialized, miss;
|
|
|
| __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
|
| FixedArray::kHeaderSize));
|
| __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate));
|
| __ j(equal, &slow_start);
|
| +
|
| + // The following cases attempt to handle MISS cases without going to the
|
| + // runtime.
|
| + if (FLAG_trace_ic) {
|
| + __ jmp(&miss);
|
| + }
|
| +
|
| __ Cmp(rcx, TypeFeedbackVector::UninitializedSentinel(isolate));
|
| + __ j(equal, &uninitialized);
|
| +
|
| + // We are going megamorphic. If the feedback is a JSFunction, it is fine
|
| + // to handle it here. More complex cases are dealt with in the runtime.
|
| + __ AssertNotSmi(rcx);
|
| + __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
|
| + __ j(not_equal, &miss);
|
| + __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
|
| + TypeFeedbackVector::MegamorphicSentinel(isolate));
|
| + // We have to update statistics for runtime profiling.
|
| + __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(-1));
|
| + __ SmiAddConstant(FieldOperand(rbx, generic_offset), Smi::FromInt(1));
|
| + __ jmp(&slow_start);
|
| +
|
| + __ bind(&uninitialized);
|
| +
|
| + // We are going monomorphic, provided we actually have a JSFunction.
|
| + __ JumpIfSmi(rdi, &miss);
|
| +
|
| + // Goto miss case if we do not have a function.
|
| + __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
|
| + __ j(not_equal, &miss);
|
| +
|
| + // Make sure the function is not the Array() function, which requires special
|
| + // behavior on MISS.
|
| + __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
|
| + __ cmpp(rdi, rcx);
|
| __ j(equal, &miss);
|
|
|
| - if (!FLAG_trace_ic) {
|
| - // We are going megamorphic. If the feedback is a JSFunction, it is fine
|
| - // to handle it here. More complex cases are dealt with in the runtime.
|
| - __ AssertNotSmi(rcx);
|
| - __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
|
| - __ j(not_equal, &miss);
|
| - __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
|
| - TypeFeedbackVector::MegamorphicSentinel(isolate));
|
| - // We have to update statistics for runtime profiling.
|
| - const int with_types_offset =
|
| - FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
|
| - __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(-1));
|
| - const int generic_offset =
|
| - FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
|
| - __ SmiAddConstant(FieldOperand(rbx, generic_offset), Smi::FromInt(1));
|
| - __ jmp(&slow_start);
|
| - }
|
| + // Update stats.
|
| + __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(1));
|
| +
|
| + // Store the function.
|
| + __ movp(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
|
| + rdi);
|
| +
|
| + // Update the write barrier.
|
| + __ movp(rax, rdi);
|
| + __ RecordWriteArray(rbx, rax, rdx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
|
| + OMIT_SMI_CHECK);
|
| + __ jmp(&have_js_function);
|
|
|
| - // We are here because tracing is on or we are going monomorphic.
|
| + // We are here because tracing is on or we encountered a MISS case we can't
|
| + // handle here.
|
| __ bind(&miss);
|
| GenerateMiss(masm);
|
|
|
|
|