From 50a829b3cfe8ec0b7ccd1b7e154e632c9a73e5f0 Mon Sep 17 00:00:00 2001 From: "weiliang.lin@intel.com" Date: Mon, 10 Nov 2014 05:50:51 +0000 Subject: [PATCH] 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 . Cr-Commit-Position: refs/heads/master@{#25230} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25230 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x87/code-stubs-x87.cc | 77 ++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc index 5d38d75455..8925d4ffb3 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); - __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); - __ 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); + // The following cases attempt to handle MISS cases without going to the + // runtime. + if (FLAG_trace_ic) { + __ jmp(&miss); } - // We are here because tracing is on or we are going monomorphic. + __ 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); + + // 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); GenerateMiss(masm);