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/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 28bcb97..c235317 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -438,14 +438,22 @@
 // about ALWAYS_INLINE (-Werror, -Wgcc-compat) in definitions.
 //
 
+// b/30419309
+#if defined(__i386__)
+#define IF_X86_OPTNONE_ELSE_ALWAYS_INLINE __attribute__((optnone))
+#else
+#define IF_X86_OPTNONE_ELSE_ALWAYS_INLINE ALWAYS_INLINE
+#endif
+
 template <bool is_range, bool do_assignability_check>
-static ALWAYS_INLINE bool DoCallCommon(ArtMethod* called_method,
-                                       Thread* self,
-                                       ShadowFrame& shadow_frame,
-                                       JValue* result,
-                                       uint16_t number_of_inputs,
-                                       uint32_t (&arg)[Instruction::kMaxVarArgRegs],
-                                       uint32_t vregC) REQUIRES_SHARED(Locks::mutator_lock_);
+IF_X86_OPTNONE_ELSE_ALWAYS_INLINE
+static bool DoCallCommon(ArtMethod* called_method,
+                         Thread* self,
+                         ShadowFrame& shadow_frame,
+                         JValue* result,
+                         uint16_t number_of_inputs,
+                         uint32_t (&arg)[Instruction::kMaxVarArgRegs],
+                         uint32_t vregC) REQUIRES_SHARED(Locks::mutator_lock_);
 
 template <bool is_range>
 ALWAYS_INLINE void CopyRegisters(ShadowFrame& caller_frame,
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index aeb438f..7ef3508 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -255,17 +255,11 @@
     }
   }
   ArtMethod* method = shadow_frame.GetMethod();
-  // MethodVerifier refuses methods with string_idx out of bounds.
-  DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize,
-            method->GetDexFile()->NumStringIds());
-  ObjPtr<mirror::String> string_ptr =
-      mirror::StringDexCachePair::Lookup(method->GetDexCache()->GetStrings(),
-                                         string_idx.index_,
-                                         mirror::DexCache::kDexCacheStringCacheSize).Read();
+  ObjPtr<mirror::String> string_ptr = method->GetDexCache()->GetResolvedString(string_idx);
   if (UNLIKELY(string_ptr == nullptr)) {
     StackHandleScope<1> hs(self);
     Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
-    string_ptr = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(),
+    string_ptr = Runtime::Current()->GetClassLinker()->ResolveString(*dex_cache->GetDexFile(),
                                                                      string_idx,
                                                                      dex_cache);
   }