Index: runtime/vm/stub_code_mips.cc |
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc |
index 30a7cdf662235846931ea7287a1886aacd19a430..58af41870b02afefe49bd1debde0f3f5e68ae828 100644 |
--- a/runtime/vm/stub_code_mips.cc |
+++ b/runtime/vm/stub_code_mips.cc |
@@ -563,7 +563,7 @@ static void GenerateDispatcherCode(Assembler* assembler, |
// Push space for the return value. |
// Push the receiver. |
- // Push IC data object. |
+ // Push ICData/MegamorphicCache object. |
// Push arguments descriptor array. |
// Push original arguments array. |
__ addiu(SP, SP, Immediate(-4 * kWordSize)); |
@@ -2211,16 +2211,16 @@ void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( |
} |
-void StubCode::EmitMegamorphicLookup( |
- Assembler* assembler, Register receiver, Register cache, Register target) { |
- ASSERT((cache != T0) && (cache != T2)); |
- __ LoadTaggedClassIdMayBeSmi(T0, receiver); |
+void StubCode::EmitMegamorphicLookup(Assembler* assembler) { |
+ __ LoadTaggedClassIdMayBeSmi(T0, T0); |
// T0: class ID of the receiver (smi). |
- __ lw(T2, FieldAddress(cache, MegamorphicCache::buckets_offset())); |
- __ lw(T1, FieldAddress(cache, MegamorphicCache::mask_offset())); |
+ __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset())); |
+ __ lw(T2, FieldAddress(S5, MegamorphicCache::buckets_offset())); |
+ __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset())); |
// T2: cache buckets array. |
// T1: mask. |
__ mov(T3, T0); |
+ // T3: probe. |
Label loop, update, call_target_function; |
__ b(&loop); |
@@ -2248,18 +2248,61 @@ void StubCode::EmitMegamorphicLookup( |
__ addu(T1, T2, T1); |
__ lw(T0, FieldAddress(T1, base + kWordSize)); |
+ __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); |
__ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); |
- __ lw(target, FieldAddress(T0, Function::entry_point_offset())); |
} |
// Called from megamorphic calls. |
-// T0: receiver. |
-// T1: lookup cache. |
+// T0: receiver |
+// S5: MegamorphicCache (preserved) |
// Result: |
-// T1: entry point. |
+// T1: target entry point |
+// CODE_REG: target Code |
+// S4: arguments descriptor |
void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
- EmitMegamorphicLookup(assembler, T0, T1, T1); |
+ EmitMegamorphicLookup(assembler); |
+ __ Ret(); |
+} |
+ |
+ |
+// Called from switchable IC calls. |
+// T0: receiver |
+// S5: ICData (preserved) |
+// Result: |
+// T1: target entry point |
+// CODE_REG: target Code object |
+// S4: arguments descriptor |
+void StubCode::GenerateICLookupStub(Assembler* assembler) { |
+ Label loop, found, miss; |
+ __ lw(T6, FieldAddress(S5, ICData::ic_data_offset())); |
+ __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
+ __ AddImmediate(T6, T6, Array::data_offset() - kHeapObjectTag); |
+ // T6: first IC entry. |
+ __ LoadTaggedClassIdMayBeSmi(T1, T0); |
+ // T1: receiver cid as Smi |
+ |
+ __ Bind(&loop); |
+ __ lw(T2, Address(T6, 0)); |
+ __ beq(T1, T2, &found); |
+ ASSERT(Smi::RawValue(kIllegalCid) == 0); |
+ __ beq(T2, ZR, &miss); |
+ |
+ const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; |
+ __ AddImmediate(T6, entry_length); // Next entry. |
+ __ b(&loop); |
+ |
+ __ Bind(&found); |
+ const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; |
+ __ lw(T0, Address(T6, target_offset)); |
+ __ lw(T1, FieldAddress(T0, Function::entry_point_offset())); |
+ __ lw(CODE_REG, FieldAddress(T0, Function::code_offset())); |
+ __ Ret(); |
+ |
+ __ Bind(&miss); |
+ __ LoadIsolate(T2); |
+ __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset())); |
+ __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset())); |
__ Ret(); |
} |