summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Lokesh Gidra <lokeshgidra@google.com> 2024-06-27 20:20:04 +0000
committer Lokesh Gidra <lokeshgidra@google.com> 2024-08-08 15:25:11 +0000
commit6f40f3867459b66ec315dd4f70f4474171065aab (patch)
treedb2ddff187f04ee0a4238de6101ebbaab15c1bed /runtime/class_linker.cc
parentf067186db77c8cca5d17a1253d9a87b2088b0c4b (diff)
Use variable sized ref-offset bitmap for fast VisitReferences()
Bug: 304325190 Test: art/test/testrunner/testrunner.py --host Change-Id: I6e25143b827acaa12ff5bd94e6196faaed461f4a
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc38
1 files changed, 6 insertions, 32 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index d0fdcf0c25..dd78be3105 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3686,13 +3686,14 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
UNREACHABLE();
}
}
- return mirror::Class::ComputeClassSize(false,
- 0,
+ return mirror::Class::ComputeClassSize(/*has_embedded_vtable=*/false,
+ /*num_vtable_entries=*/0,
num_8,
num_16,
num_32,
num_64,
num_ref,
+ /*num_ref_bitmap_entries=*/0,
image_pointer_size_);
}
@@ -6335,7 +6336,8 @@ bool ClassLinker::LinkClass(Thread* self,
if (!LinkStaticFields(self, klass, &class_size)) {
return false;
}
- CreateReferenceInstanceOffsets(klass);
+ class_size =
+ mirror::Class::AdjustClassSizeForReferenceOffsetBitmapDuringLinking(klass.Get(), class_size);
CHECK_EQ(ClassStatus::kLoaded, klass->GetStatus());
ImTable* imt = nullptr;
@@ -6377,6 +6379,7 @@ bool ClassLinker::LinkClass(Thread* self,
if (klass->ShouldHaveEmbeddedVTable()) {
klass->PopulateEmbeddedVTable(image_pointer_size_);
+ klass->PopulateReferenceOffsetBitmap();
}
if (klass->ShouldHaveImt()) {
klass->SetImt(imt, image_pointer_size_);
@@ -9882,35 +9885,6 @@ bool ClassLinker::VerifyRecordClass(Handle<mirror::Class> klass, ObjPtr<mirror::
return true;
}
-// Set the bitmap of reference instance field offsets.
-void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) {
- uint32_t reference_offsets = 0;
- ObjPtr<mirror::Class> super_class = klass->GetSuperClass();
- // Leave the reference offsets as 0 for mirror::Object (the class field is handled specially).
- if (super_class != nullptr) {
- reference_offsets = super_class->GetReferenceInstanceOffsets();
- // Compute reference offsets unless our superclass overflowed.
- if (reference_offsets != mirror::Class::kClassWalkSuper) {
- size_t num_reference_fields = klass->NumReferenceInstanceFieldsDuringLinking();
- if (num_reference_fields != 0u) {
- // All of the fields that contain object references are guaranteed be grouped in memory
- // starting at an appropriately aligned address after super class object data.
- uint32_t start_offset = RoundUp(super_class->GetObjectSize(),
- sizeof(mirror::HeapReference<mirror::Object>));
- uint32_t start_bit = (start_offset - mirror::kObjectHeaderSize) /
- sizeof(mirror::HeapReference<mirror::Object>);
- if (start_bit + num_reference_fields > 32) {
- reference_offsets = mirror::Class::kClassWalkSuper;
- } else {
- reference_offsets |= (0xffffffffu << start_bit) &
- (0xffffffffu >> (32 - (start_bit + num_reference_fields)));
- }
- }
- }
- }
- klass->SetReferenceInstanceOffsets(reference_offsets);
-}
-
ObjPtr<mirror::String> ClassLinker::DoResolveString(dex::StringIndex string_idx,
ObjPtr<mirror::DexCache> dex_cache) {
StackHandleScope<1> hs(Thread::Current());