summaryrefslogtreecommitdiff
path: root/runtime/mirror/class-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/class-inl.h')
-rw-r--r--runtime/mirror/class-inl.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 40f119e3c4..373b9b3105 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -1356,6 +1356,38 @@ inline ImTable* Class::FindSuperImt(PointerSize pointer_size) {
return nullptr;
}
+ALWAYS_INLINE FLATTEN inline ArtField* Class::FindDeclaredField(uint32_t dex_field_idx) {
+ size_t num_fields = NumFields();
+ if (num_fields > 0) {
+ // The field array is an ordered list of fields where there may be missing
+ // indices. For example, it could be [40, 42], but in 90% of cases cases we have
+ // [40, 41, 42]. The latter is the case we are optimizing for, where for
+ // example `dex_field_idx` is 41, and we can just substract it with the
+ // first field index (40) and directly access the array with that index (1).
+ uint32_t index = dex_field_idx - GetField(0)->GetDexFieldIndex();
+ if (index < num_fields) {
+ ArtField* field = GetField(index);
+ if (field->GetDexFieldIndex() == dex_field_idx) {
+ return field;
+ }
+ } else {
+ index = num_fields;
+ }
+ // If there is a field, it's down the array. The array is ordered by field
+ // index, so we know we can stop the search if `dex_field_idx` is greater
+ // than the current field's index.
+ for (; index > 0; --index) {
+ ArtField* field = GetField(index - 1);
+ if (field->GetDexFieldIndex() == dex_field_idx) {
+ return field;
+ } else if (field->GetDexFieldIndex() < dex_field_idx) {
+ break;
+ }
+ }
+ }
+ return nullptr;
+}
+
} // namespace mirror
} // namespace art