Index: src/arm64/code-stubs-arm64.cc |
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc |
index bdcd08aefe3fd26302c35529c0ce650e45b9a33e..e005c8a82f91ece309d8c97b3bc57044459e857f 100644 |
--- a/src/arm64/code-stubs-arm64.cc |
+++ b/src/arm64/code-stubs-arm64.cc |
@@ -3016,6 +3016,10 @@ void CallICStub::Generate(MacroAssembler* masm) { |
// x1 - function |
// x3 - slot id (Smi) |
+ 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; |
@@ -3064,35 +3068,72 @@ void CallICStub::Generate(MacroAssembler* masm) { |
} |
__ bind(&extra_checks_or_miss); |
- Label miss; |
+ Label uninitialized, miss; |
__ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start); |
- __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &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(x4); |
- __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); |
- __ Add(x4, feedback_vector, |
- Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
- __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); |
- __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
- // We have to update statistics for runtime profiling. |
- const int with_types_offset = |
- FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
- __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
- __ Subs(x4, x4, Operand(Smi::FromInt(1))); |
- __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
- const int generic_offset = |
- FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
- __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); |
- __ Adds(x4, x4, Operand(Smi::FromInt(1))); |
- __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); |
- __ B(&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. |
+ __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss); |
+ |
+ // 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(x4); |
+ __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); |
+ __ Add(x4, feedback_vector, |
+ Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
+ __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); |
+ __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
+ // We have to update statistics for runtime profiling. |
+ __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
+ __ Subs(x4, x4, Operand(Smi::FromInt(1))); |
+ __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
+ __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset)); |
+ __ Adds(x4, x4, Operand(Smi::FromInt(1))); |
+ __ Str(x4, FieldMemOperand(feedback_vector, generic_offset)); |
+ __ B(&slow_start); |
+ |
+ __ bind(&uninitialized); |
+ |
+ // We are going monomorphic, provided we actually have a JSFunction. |
+ __ JumpIfSmi(function, &miss); |
+ |
+ // Goto miss case if we do not have a function. |
+ __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); |
+ |
+ // Make sure the function is not the Array() function, which requires special |
+ // behavior on MISS. |
+ __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, x5); |
+ __ Cmp(function, x5); |
+ __ B(eq, &miss); |
+ |
+ // Update stats. |
+ __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
+ __ Adds(x4, x4, Operand(Smi::FromInt(1))); |
+ __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset)); |
+ |
+ // Store the function. |
+ __ Add(x4, feedback_vector, |
+ Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
+ __ Str(function, FieldMemOperand(x4, FixedArray::kHeaderSize)); |
+ |
+ __ Add(x4, feedback_vector, |
+ Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
+ __ Add(x4, x4, FixedArray::kHeaderSize - kHeapObjectTag); |
+ __ Str(function, MemOperand(x4, 0)); |
+ |
+ // Update the write barrier. |
+ __ Mov(x5, function); |
+ __ RecordWrite(feedback_vector, x4, x5, kLRHasNotBeenSaved, kDontSaveFPRegs, |
+ EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
+ __ B(&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); |