| Index: src/x87/code-stubs-x87.cc
|
| diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc
|
| index 5d38d75455b1994b4c8e59d6d206f95a53d17685..8925d4ffb35574a2142260eae04a6eafe2c8015d 100644
|
| --- a/src/x87/code-stubs-x87.cc
|
| +++ b/src/x87/code-stubs-x87.cc
|
| @@ -1900,6 +1900,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
| // edi - function
|
| // edx - 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;
|
| @@ -1939,35 +1943,66 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
| }
|
|
|
| __ bind(&extra_checks_or_miss);
|
| - Label miss;
|
| + Label uninitialized, miss;
|
|
|
| __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
|
| FixedArray::kHeaderSize));
|
| __ cmp(ecx, Immediate(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(ecx, Immediate(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(ecx);
|
| + __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
|
| + __ j(not_equal, &miss);
|
| + __ mov(
|
| + FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
|
| + Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
| + // We have to update statistics for runtime profiling.
|
| + __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
|
| + __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
|
| + __ jmp(&slow_start);
|
| +
|
| + __ bind(&uninitialized);
|
| +
|
| + // We are going monomorphic, provided we actually have a JSFunction.
|
| + __ JumpIfSmi(edi, &miss);
|
| +
|
| + // Goto miss case if we do not have a function.
|
| + __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
|
| + __ j(not_equal, &miss);
|
| +
|
| + // Make sure the function is not the Array() function, which requires special
|
| + // behavior on MISS.
|
| + __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
|
| + __ cmp(edi, ecx);
|
| __ 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(ecx);
|
| - __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
|
| - __ j(not_equal, &miss);
|
| - __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
|
| - FixedArray::kHeaderSize),
|
| - Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
| - // We have to update statistics for runtime profiling.
|
| - const int with_types_offset =
|
| - FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
|
| - __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
|
| - const int generic_offset =
|
| - FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
|
| - __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
|
| - __ jmp(&slow_start);
|
| - }
|
| + // Update stats.
|
| + __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
|
| +
|
| + // Store the function.
|
| + __ mov(
|
| + FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
|
| + edi);
|
| +
|
| + // Update the write barrier.
|
| + __ mov(eax, edi);
|
| + __ RecordWriteArray(ebx, eax, edx, 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);
|
|
|
|
|