diff options
author | 2024-05-09 07:45:02 +0000 | |
---|---|---|
committer | 2024-05-13 06:04:55 +0000 | |
commit | ffc0d1f69841fe4dcc8dca0676fb13466b9b8132 (patch) | |
tree | bc0846ea69dd927ac32be495a5fea03ef52af9dd | |
parent | 0bfa9a15cca4fbd2710ee3eead13bdd4dccaf86b (diff) |
Faster `ClassTable::UpdateClass()`.
In the `ClassTable::UpdateClass()`, both the old and the new
`Class` objects reference the same dex file and type index.
Therefore it's better to do the lookup with the new `Class`
object as the `Class:DescriptorEquals(ObjPtr<Class>)` can
avoid the string comparison for the descriptor match in this
case and we compare descriptors only for hash conflicts.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 338123769
Change-Id: I23960c9c3b34b7f7fdd2fce6b191fd9c4efe7320
-rw-r--r-- | runtime/class_linker.cc | 2 | ||||
-rw-r--r-- | runtime/class_table.cc | 28 | ||||
-rw-r--r-- | runtime/class_table.h | 4 |
3 files changed, 16 insertions, 18 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 08cc153d84..501470c4b5 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -6403,7 +6403,7 @@ bool ClassLinker::LinkClass(Thread* self, const ObjPtr<mirror::ClassLoader> class_loader = h_new_class.Get()->GetClassLoader(); ClassTable* const table = InsertClassTableForClassLoader(class_loader); const ObjPtr<mirror::Class> existing = - table->UpdateClass(descriptor, h_new_class.Get(), ComputeModifiedUtf8Hash(descriptor)); + table->UpdateClass(h_new_class.Get(), ComputeModifiedUtf8Hash(descriptor)); CHECK_EQ(existing, klass.Get()); WriteBarrierOnClassLoaderLocked(class_loader, h_new_class.Get()); } diff --git a/runtime/class_table.cc b/runtime/class_table.cc index f66bd1e7ad..35d3537478 100644 --- a/runtime/class_table.cc +++ b/runtime/class_table.cc @@ -38,30 +38,30 @@ void ClassTable::FreezeSnapshot() { classes_.push_back(std::move(new_set)); } -ObjPtr<mirror::Class> ClassTable::UpdateClass(const char* descriptor, - ObjPtr<mirror::Class> klass, - size_t hash) { +ObjPtr<mirror::Class> ClassTable::UpdateClass(ObjPtr<mirror::Class> klass, size_t hash) { WriterMutexLock mu(Thread::Current(), lock_); // Should only be updating latest table. - DescriptorHashPair pair(descriptor, hash); - auto existing_it = classes_.back().FindWithHash(pair, hash); - if (existing_it == classes_.back().end()) { + TableSlot slot(klass, hash); + auto existing_it = classes_.back().FindWithHash(slot, hash); + if (UNLIKELY(existing_it == classes_.back().end())) { for (const ClassSet& class_set : classes_) { - if (class_set.FindWithHash(pair, hash) != class_set.end()) { - LOG(FATAL) << "Updating class found in frozen table " << descriptor; + if (class_set.FindWithHash(slot, hash) != class_set.end()) { + LOG(FATAL) << "Updating class found in frozen table " << klass->PrettyDescriptor(); + UNREACHABLE(); } } - LOG(FATAL) << "Updating class not found " << descriptor; + LOG(FATAL) << "Updating class not found " << klass->PrettyDescriptor(); + UNREACHABLE(); } const ObjPtr<mirror::Class> existing = existing_it->Read(); - CHECK_NE(existing, klass) << descriptor; - CHECK(!existing->IsResolved()) << descriptor; - CHECK_EQ(klass->GetStatus(), ClassStatus::kResolving) << descriptor; - CHECK(!klass->IsTemp()) << descriptor; + CHECK_NE(existing, klass) << klass->PrettyDescriptor(); + CHECK(!existing->IsResolved()) << klass->PrettyDescriptor(); + CHECK_EQ(klass->GetStatus(), ClassStatus::kResolving) << klass->PrettyDescriptor(); + CHECK(!klass->IsTemp()) << klass->PrettyDescriptor(); VerifyObject(klass); // Update the element in the hash set with the new class. This is safe to do since the descriptor // doesn't change. - *existing_it = TableSlot(klass, hash); + *existing_it = slot; return existing; } diff --git a/runtime/class_table.h b/runtime/class_table.h index 1c9b0ce2e9..3374622f00 100644 --- a/runtime/class_table.h +++ b/runtime/class_table.h @@ -187,9 +187,7 @@ class ClassTable { REQUIRES_SHARED(Locks::mutator_lock_); // Update a class in the table with the new class. Returns the existing class which was replaced. - ObjPtr<mirror::Class> UpdateClass(const char* descriptor, - ObjPtr<mirror::Class> new_klass, - size_t hash) + ObjPtr<mirror::Class> UpdateClass(ObjPtr<mirror::Class> new_klass, size_t hash) REQUIRES(!lock_) REQUIRES_SHARED(Locks::mutator_lock_); |