diff options
author | 2024-06-27 20:20:04 +0000 | |
---|---|---|
committer | 2024-08-08 15:25:11 +0000 | |
commit | 6f40f3867459b66ec315dd4f70f4474171065aab (patch) | |
tree | db2ddff187f04ee0a4238de6101ebbaab15c1bed /runtime/class_linker.cc | |
parent | f067186db77c8cca5d17a1253d9a87b2088b0c4b (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.cc | 38 |
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()); |