Hash-based dex cache type array.

Test: m test-art-host (Interpreter, Optimizing, JIT)
Test: m test-art-target on Nexus 6P (Interpreter, Optimizing, JIT)
Test: Nexus 6P boots
Test: m valgrind-test-art-host
Bug: 30627598
Bug: 34659969
Bug: 30419309
Change-Id: Ic00eda89e58088a3573fc9ec0ad04c0e69e161d1
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index 741cf3b..3103a92 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -58,8 +58,8 @@
 
   mirror::StringDexCacheType* strings = (dex_file->NumStringIds() == 0u) ? nullptr :
       reinterpret_cast<mirror::StringDexCacheType*>(raw_arrays + layout.StringsOffset());
-  GcRoot<mirror::Class>* types = (dex_file->NumTypeIds() == 0u) ? nullptr :
-      reinterpret_cast<GcRoot<mirror::Class>*>(raw_arrays + layout.TypesOffset());
+  mirror::TypeDexCacheType* types = (dex_file->NumTypeIds() == 0u) ? nullptr :
+      reinterpret_cast<mirror::TypeDexCacheType*>(raw_arrays + layout.TypesOffset());
   ArtMethod** methods = (dex_file->NumMethodIds() == 0u) ? nullptr :
       reinterpret_cast<ArtMethod**>(raw_arrays + layout.MethodsOffset());
   ArtField** fields = (dex_file->NumFieldIds() == 0u) ? nullptr :
@@ -69,6 +69,10 @@
   if (dex_file->NumStringIds() < num_strings) {
     num_strings = dex_file->NumStringIds();
   }
+  size_t num_types = mirror::DexCache::kDexCacheTypeCacheSize;
+  if (dex_file->NumTypeIds() < num_types) {
+    num_types = dex_file->NumTypeIds();
+  }
 
   // Note that we allocate the method type dex caches regardless of this flag,
   // and we make sure here that they're not used by the runtime. This is in the
@@ -104,8 +108,9 @@
       CHECK_EQ(strings[i].load(std::memory_order_relaxed).index, 0u);
       CHECK(strings[i].load(std::memory_order_relaxed).object.IsNull());
     }
-    for (size_t i = 0; i < dex_file->NumTypeIds(); ++i) {
-      CHECK(types[i].IsNull());
+    for (size_t i = 0; i < num_types; ++i) {
+      CHECK_EQ(types[i].load(std::memory_order_relaxed).index, 0u);
+      CHECK(types[i].load(std::memory_order_relaxed).object.IsNull());
     }
     for (size_t i = 0; i < dex_file->NumMethodIds(); ++i) {
       CHECK(mirror::DexCache::GetElementPtrSize(methods, i, image_pointer_size) == nullptr);
@@ -121,6 +126,9 @@
   if (strings != nullptr) {
     mirror::StringDexCachePair::Initialize(strings);
   }
+  if (types != nullptr) {
+    mirror::TypeDexCachePair::Initialize(types);
+  }
   if (method_types != nullptr) {
     mirror::MethodTypeDexCachePair::Initialize(method_types);
   }
@@ -129,7 +137,7 @@
                   strings,
                   num_strings,
                   types,
-                  dex_file->NumTypeIds(),
+                  num_types,
                   methods,
                   dex_file->NumMethodIds(),
                   fields,
@@ -143,7 +151,7 @@
                     ObjPtr<String> location,
                     StringDexCacheType* strings,
                     uint32_t num_strings,
-                    GcRoot<Class>* resolved_types,
+                    TypeDexCacheType* resolved_types,
                     uint32_t num_resolved_types,
                     ArtMethod** resolved_methods,
                     uint32_t num_resolved_methods,