Index: src/mips/code-stubs-mips.cc |
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc |
index c8db844200f68b8d26786cb38fff8fb5360487c0..5b34cc21f4fcf9ea3a6c174b22a8788822d9e0a0 100644 |
--- a/src/mips/code-stubs-mips.cc |
+++ b/src/mips/code-stubs-mips.cc |
@@ -2829,8 +2829,12 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { |
void CallICStub::Generate(MacroAssembler* masm) { |
- // r1 - function |
- // r3 - slot id (Smi) |
+ // a1 - function |
+ // a3 - 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; |
@@ -2869,38 +2873,71 @@ void CallICStub::Generate(MacroAssembler* masm) { |
} |
__ bind(&extra_checks_or_miss); |
- Label miss; |
+ Label uninitialized, miss; |
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
__ Branch(&slow_start, eq, t0, Operand(at)); |
- __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
- __ Branch(&miss, eq, t0, Operand(at)); |
- |
- 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(t0); |
- __ GetObjectType(t0, t1, t1); |
- __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); |
- __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
- __ Addu(t0, a2, Operand(t0)); |
- __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
- __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
- // We have to update statistics for runtime profiling. |
- const int with_types_offset = |
- FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
- __ lw(t0, FieldMemOperand(a2, with_types_offset)); |
- __ Subu(t0, t0, Operand(Smi::FromInt(1))); |
- __ sw(t0, FieldMemOperand(a2, with_types_offset)); |
- const int generic_offset = |
- FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
- __ lw(t0, FieldMemOperand(a2, generic_offset)); |
- __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
- __ sw(t0, FieldMemOperand(a2, generic_offset)); |
- __ Branch(&slow_start); |
+ |
+ // The following cases attempt to handle MISS cases without going to the |
+ // runtime. |
+ if (FLAG_trace_ic) { |
+ __ Branch(&miss); |
} |
- // We are here because tracing is on or we are going monomorphic. |
+ __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
+ __ Branch(&uninitialized, eq, t0, Operand(at)); |
+ |
+ // 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(t0); |
+ __ GetObjectType(t0, t1, t1); |
+ __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); |
+ __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
+ __ Addu(t0, a2, Operand(t0)); |
+ __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
+ __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
+ // We have to update statistics for runtime profiling. |
+ __ lw(t0, FieldMemOperand(a2, with_types_offset)); |
+ __ Subu(t0, t0, Operand(Smi::FromInt(1))); |
+ __ sw(t0, FieldMemOperand(a2, with_types_offset)); |
+ __ lw(t0, FieldMemOperand(a2, generic_offset)); |
+ __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
+ __ Branch(USE_DELAY_SLOT, &slow_start); |
+ __ sw(t0, FieldMemOperand(a2, generic_offset)); // In delay slot. |
+ |
+ __ bind(&uninitialized); |
+ |
+ // We are going monomorphic, provided we actually have a JSFunction. |
+ __ JumpIfSmi(a1, &miss); |
+ |
+ // Goto miss case if we do not have a function. |
+ __ GetObjectType(a1, t0, t0); |
+ __ Branch(&miss, ne, t0, Operand(JS_FUNCTION_TYPE)); |
+ |
+ // Make sure the function is not the Array() function, which requires special |
+ // behavior on MISS. |
+ __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); |
+ __ Branch(&miss, eq, a1, Operand(t0)); |
+ |
+ // Update stats. |
+ __ lw(t0, FieldMemOperand(a2, with_types_offset)); |
+ __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
+ __ sw(t0, FieldMemOperand(a2, with_types_offset)); |
+ |
+ // Store the function. |
+ __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
+ __ Addu(t0, a2, Operand(t0)); |
+ __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
+ __ sw(a1, MemOperand(t0, 0)); |
+ |
+ // Update the write barrier. |
+ __ mov(t1, a1); |
+ __ RecordWrite(a2, t0, t1, kRAHasNotBeenSaved, kDontSaveFPRegs, |
+ EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
+ __ Branch(&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); |