| 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);
|
|
|
|
|