Add hash map, reduce excessive hashing
Changed the class def index to use a HashMap instead of unordered_map
so that we can use FindWithHash to reduce how often we need to compute
hashes.
Fixed a bug in ClassLinker::UpdateClass where we didn't properly
handle classes with the same descriptor but different class loaders.
Introduced by previous CL.
Before (fb launch):
1.74% art::ComputeModifiedUtf8Hash(char const*)
After:
0.95% art::ComputeModifiedUtf8Hash(char const*)
Bug: 18054905
Bug: 16828525
Change-Id: Iba2ee37c9837289e0ea187800ba4af322225a994
(cherry picked from commit 564ff985184737977aa26c485d0c1a413e530705)
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 16bc33f..3d4184b 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -419,11 +419,12 @@
return atoi(version);
}
-const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
+const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const {
+ DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
// If we have an index lookup the descriptor via that as its constant time to search.
Index* index = class_def_index_.LoadSequentiallyConsistent();
if (index != nullptr) {
- auto it = index->find(descriptor);
+ auto it = index->FindWithHash(descriptor, hash);
return (it == index->end()) ? nullptr : it->second;
}
// Fast path for rate no class defs case.
@@ -455,11 +456,11 @@
// Are we the ones moving the miss count past the max? Sanity check the index doesn't exist.
CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr);
// Build the index.
- index = new Index(num_class_defs);
+ index = new Index();
for (uint32_t i = 0; i < num_class_defs; ++i) {
const ClassDef& class_def = GetClassDef(i);
const char* class_descriptor = GetClassDescriptor(class_def);
- index->insert(std::make_pair(class_descriptor, &class_def));
+ index->Insert(std::make_pair(class_descriptor, &class_def));
}
// Sanity check the index still doesn't exist, only 1 thread should build it.
CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr);