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);