summaryrefslogtreecommitdiff
path: root/runtime/mirror/class.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2025-02-24 17:29:54 -0800
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-02-24 17:29:54 -0800
commit007e70a8fd33a91da503bb4ffeee71840ed55572 (patch)
treedd2b10e277ba9741fd7285957cc0f559b384ce92 /runtime/mirror/class.cc
parent5dbdbcd4b78a4c134ff7076aeef4d2000ed11481 (diff)
parentd4f0c4c03b9347e4549b03b1cb05401171a12610 (diff)
Optimize field lookup. am: 4421e7c33e am: d4f0c4c03b
Original change: https://android-review.googlesource.com/c/platform/art/+/3463959 Change-Id: I2bf9721986f0f4b23bd08036679a1b1fdf918063 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'runtime/mirror/class.cc')
-rw-r--r--runtime/mirror/class.cc29
1 files changed, 25 insertions, 4 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index fe923cbaa6..0bf1b1cc0a 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1173,10 +1173,31 @@ ArtField* Class::FindDeclaredStaticField(std::string_view name, std::string_view
}
ArtField* Class::FindDeclaredField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx) {
- if (dex_cache == GetDexCache()) {
- for (ArtField& field : GetFields()) {
- if (field.GetDexFieldIndex() == dex_field_idx) {
- return &field;
+ size_t num_fields = NumFields();
+ if (dex_cache == GetDexCache() && 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;
}
}
}