ART: Add guards to the dex cache and its shortcuts

Do not return fields, methods or classes if the (declaring) class is
erroneous.

Bug: 16692788
Change-Id: If43c2414ad0eb22db5eba7cf66396c7f16c26597
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 73de683..0dd1588 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -19,6 +19,8 @@
 
 #include "art_method.h"
 
+#include "art_field.h"
+#include "class.h"
 #include "class_linker.h"
 #include "dex_cache.h"
 #include "dex_file.h"
@@ -87,11 +89,60 @@
       OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_));
 }
 
+inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index) {
+  ArtMethod* method = GetDexCacheResolvedMethods()->Get(method_index);
+  if (method != nullptr && !method->GetDeclaringClass()->IsErroneous()) {
+    return method;
+  } else {
+    return nullptr;
+  }
+}
+
+inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method) {
+  GetDexCacheResolvedMethods()->Set<false>(method_idx, new_method);
+}
+
+inline bool ArtMethod::HasDexCacheResolvedMethods() {
+  return GetDexCacheResolvedMethods() != nullptr;
+}
+
+inline bool ArtMethod::HasSameDexCacheResolvedMethods(ObjectArray<ArtMethod>* other_cache) {
+  return GetDexCacheResolvedMethods() == other_cache;
+}
+
+inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other) {
+  return GetDexCacheResolvedMethods() == other->GetDexCacheResolvedMethods();
+}
+
+
 inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() {
   return GetFieldObject<ObjectArray<Class>>(
       OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_));
 }
 
+template <bool kWithCheck>
+inline Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index) {
+  Class* klass;
+  if (kWithCheck) {
+    klass = GetDexCacheResolvedTypes()->Get(type_index);
+  } else {
+    klass = GetDexCacheResolvedTypes()->GetWithoutChecks(type_index);
+  }
+  return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr;
+}
+
+inline bool ArtMethod::HasDexCacheResolvedTypes() {
+  return GetDexCacheResolvedTypes() != nullptr;
+}
+
+inline bool ArtMethod::HasSameDexCacheResolvedTypes(ObjectArray<Class>* other_cache) {
+  return GetDexCacheResolvedTypes() == other_cache;
+}
+
+inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other) {
+  return GetDexCacheResolvedTypes() == other->GetDexCacheResolvedTypes();
+}
+
 inline uint32_t ArtMethod::GetCodeSize() {
   DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
   const void* code = EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode());
@@ -396,7 +447,7 @@
 
 inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) {
   mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
-  return method->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr;
+  return method->GetDexCacheResolvedType(type_idx) != nullptr;
 }
 
 inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {