X87: Try avoiding MISS for callic monomorphic case.
port 6412c8ba70f2331aae0f21b968dd051b2320b947 (r25207) original commit message: Try avoiding MISS for callic monomorphic case. BUG= R=weiliang.lin@intel.com Review URL: https://codereview.chromium.org/713743003 Patch from Chunyang Dai <chunyang.dai@intel.com>. Cr-Commit-Position: refs/heads/master@{#25230} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25230 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c53fa96773
commit
50a829b3cf
@ -1900,6 +1900,10 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
|||||||
// edi - function
|
// edi - function
|
||||||
// edx - slot id
|
// edx - slot id
|
||||||
Isolate* isolate = masm->isolate();
|
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 extra_checks_or_miss, slow_start;
|
||||||
Label slow, non_function, wrap, cont;
|
Label slow, non_function, wrap, cont;
|
||||||
Label have_js_function;
|
Label have_js_function;
|
||||||
@ -1939,35 +1943,66 @@ void CallICStub::Generate(MacroAssembler* masm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__ bind(&extra_checks_or_miss);
|
__ bind(&extra_checks_or_miss);
|
||||||
Label miss;
|
Label uninitialized, miss;
|
||||||
|
|
||||||
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
|
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
|
||||||
FixedArray::kHeaderSize));
|
FixedArray::kHeaderSize));
|
||||||
__ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
__ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
||||||
__ j(equal, &slow_start);
|
__ j(equal, &slow_start);
|
||||||
__ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate)));
|
|
||||||
__ j(equal, &miss);
|
|
||||||
|
|
||||||
if (!FLAG_trace_ic) {
|
// 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
|
// 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.
|
// to handle it here. More complex cases are dealt with in the runtime.
|
||||||
__ AssertNotSmi(ecx);
|
__ AssertNotSmi(ecx);
|
||||||
__ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
|
__ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
|
||||||
__ j(not_equal, &miss);
|
__ j(not_equal, &miss);
|
||||||
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
|
__ mov(
|
||||||
FixedArray::kHeaderSize),
|
FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
|
||||||
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
|
||||||
// We have to update statistics for runtime profiling.
|
// 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)));
|
__ 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)));
|
__ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
|
||||||
__ jmp(&slow_start);
|
__ jmp(&slow_start);
|
||||||
}
|
|
||||||
|
|
||||||
// We are here because tracing is on or we are going monomorphic.
|
__ 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);
|
||||||
|
|
||||||
|
// 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 encountered a MISS case we can't
|
||||||
|
// handle here.
|
||||||
__ bind(&miss);
|
__ bind(&miss);
|
||||||
GenerateMiss(masm);
|
GenerateMiss(masm);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user