summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2022-04-12 11:27:34 +0100
committer Vladimir Marko <vmarko@google.com> 2022-04-12 13:22:19 +0000
commit7a0478394749f206544fb86841bd6c62dc87f005 (patch)
tree900f6067114bf7897cb1c6ee939db3121f0badba
parent53258d07c179d8530adcf8c73848e114830c913c (diff)
dex2oat: Faster class pruning.
Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 181943478 Change-Id: I0f4facc13ded5e5a5755fe9bec1c32449049129a
-rw-r--r--dex2oat/linker/image_writer.cc18
-rw-r--r--runtime/class_table.cc13
-rw-r--r--runtime/class_table.h5
-rw-r--r--runtime/class_table_test.cc5
4 files changed, 13 insertions, 28 deletions
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 51daa30a83..c0dea85434 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -1108,12 +1108,20 @@ class ImageWriter::PruneClassesVisitor : public ClassVisitor {
size_t Prune() REQUIRES_SHARED(Locks::mutator_lock_) {
ClassTable* class_table =
Runtime::Current()->GetClassLinker()->ClassTableForClassLoader(class_loader_);
+ WriterMutexLock mu(Thread::Current(), class_table->lock_);
for (mirror::Class* klass : classes_to_prune_) {
- std::string storage;
- const char* descriptor = klass->GetDescriptor(&storage);
- bool result = class_table->Remove(descriptor);
- DCHECK(result);
- DCHECK(!class_table->Remove(descriptor)) << descriptor;
+ uint32_t hash = ClassTable::TableSlot::HashDescriptor(klass);
+ DCHECK(!class_table->classes_.empty());
+ ClassTable::ClassSet& last_class_set = class_table->classes_.back();
+ auto it = last_class_set.FindWithHash(ClassTable::TableSlot(klass, hash), hash);
+ DCHECK(it != last_class_set.end());
+ last_class_set.erase(it);
+ DCHECK(std::none_of(class_table->classes_.begin(),
+ class_table->classes_.end(),
+ [klass, hash](ClassTable::ClassSet& class_set) {
+ ClassTable::TableSlot slot(klass, hash);
+ return class_set.FindWithHash(slot, hash) != class_set.end();
+ }));
}
return defined_class_count_;
}
diff --git a/runtime/class_table.cc b/runtime/class_table.cc
index acfbcb09a3..4bc2fe6833 100644
--- a/runtime/class_table.cc
+++ b/runtime/class_table.cc
@@ -153,19 +153,6 @@ void ClassTable::InsertWithHash(ObjPtr<mirror::Class> klass, size_t hash) {
classes_.back().InsertWithHash(TableSlot(klass, hash), hash);
}
-bool ClassTable::Remove(const char* descriptor) {
- DescriptorHashPair pair(descriptor, ComputeModifiedUtf8Hash(descriptor));
- WriterMutexLock mu(Thread::Current(), lock_);
- for (ClassSet& class_set : classes_) {
- auto it = class_set.find(pair);
- if (it != class_set.end()) {
- class_set.erase(it);
- return true;
- }
- }
- return false;
-}
-
bool ClassTable::InsertStrongRoot(ObjPtr<mirror::Object> obj) {
WriterMutexLock mu(Thread::Current(), lock_);
DCHECK(obj != nullptr);
diff --git a/runtime/class_table.h b/runtime/class_table.h
index 4c5fc62b2d..3377f14b4a 100644
--- a/runtime/class_table.h
+++ b/runtime/class_table.h
@@ -220,11 +220,6 @@ class ClassTable {
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Returns true if the class was found and removed, false otherwise.
- bool Remove(const char* descriptor)
- REQUIRES(!lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Return true if we inserted the strong root, false if it already exists.
bool InsertStrongRoot(ObjPtr<mirror::Object> obj)
REQUIRES(!lock_)
diff --git a/runtime/class_table_test.cc b/runtime/class_table_test.cc
index d9f53ed6a2..7dbeba51c0 100644
--- a/runtime/class_table_test.cc
+++ b/runtime/class_table_test.cc
@@ -137,12 +137,7 @@ TEST_F(ClassTableTest, ClassTable) {
});
EXPECT_EQ(classes.size(), 1u);
- // Test remove.
- table.Remove(descriptor_x);
- EXPECT_TRUE(table.LookupByDescriptor(h_X.Get()) == nullptr);
-
// Test that reading a class set from memory works.
- table.Insert(h_X.Get());
ClassTable::ClassSet temp_set;
table.Visit([&temp_set](ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
temp_set.insert(ClassTable::TableSlot(klass));