From 6f40f3867459b66ec315dd4f70f4474171065aab Mon Sep 17 00:00:00 2001 From: Lokesh Gidra Date: Thu, 27 Jun 2024 20:20:04 +0000 Subject: Use variable sized ref-offset bitmap for fast VisitReferences() Bug: 304325190 Test: art/test/testrunner/testrunner.py --host Change-Id: I6e25143b827acaa12ff5bd94e6196faaed461f4a --- runtime/class_linker.cc | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'runtime/class_linker.cc') 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 klass, ObjPtr klass) { - uint32_t reference_offsets = 0; - ObjPtr 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)); - uint32_t start_bit = (start_offset - mirror::kObjectHeaderSize) / - sizeof(mirror::HeapReference); - 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 ClassLinker::DoResolveString(dex::StringIndex string_idx, ObjPtr dex_cache) { StackHandleScope<1> hs(Thread::Current()); -- cgit v1.2.3-59-g8ed1b