Index: runtime/vm/stub_code_arm.cc |
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc |
index 6b8812e3a5b57e1c069d318cbddab02c2faa9481..9a31d4271410429dfb1b5ec7eeed4ee288ef55bd 100644 |
--- a/runtime/vm/stub_code_arm.cc |
+++ b/runtime/vm/stub_code_arm.cc |
@@ -2110,7 +2110,7 @@ void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
// R1: target entry point |
// CODE_REG: target Code object |
// R4: arguments descriptor |
-void StubCode::GenerateICLookupStub(Assembler* assembler) { |
+void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { |
Label loop, found, miss; |
__ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); |
__ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
@@ -2144,6 +2144,41 @@ void StubCode::GenerateICLookupStub(Assembler* assembler) { |
__ Ret(); |
} |
+ |
+void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { |
+ Label loop, found, miss; |
+ __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset())); |
+ __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset())); |
+ __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); |
+ // R8: first IC entry |
+ __ LoadTaggedClassIdMayBeSmi(R1, R0); |
+ // R1: receiver cid as Smi |
+ |
+ __ Bind(&loop); |
+ __ ldr(R2, Address(R8, 0)); |
+ __ cmp(R1, Operand(R2)); |
+ __ b(&found, EQ); |
+ __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); |
+ __ b(&miss, EQ); |
+ |
+ const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; |
+ __ AddImmediate(R8, entry_length); // Next entry. |
+ __ b(&loop); |
+ |
+ __ Bind(&found); |
+ const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; |
+ const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; |
+ __ ldr(R1, Address(R8, entry_offset)); |
+ __ ldr(CODE_REG, Address(R8, code_offset)); |
+ __ Ret(); |
+ |
+ __ Bind(&miss); |
+ __ LoadIsolate(R2); |
+ __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); |
+ __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); |
+ __ Ret(); |
+} |
+ |
} // namespace dart |
#endif // defined TARGET_ARCH_ARM |