Don't resolve types in verifier when we can't load classes.

Added a boolean parameter to GetReturnType which tells us whether or
not we can resolve types. We pass in can_load_classes_.

Bug: 11689500
Change-Id: Ib3d35f441e08c2409ce14ac269854012dc978ddd
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 084e1e2..407aa65 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -417,12 +417,12 @@
     return GetDexFile().GetProtoParameters(proto);
   }
 
-  mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
     const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
     uint16_t return_type_idx = proto_id.return_type_idx_;
-    return GetClassFromTypeIdx(return_type_idx);
+    return GetClassFromTypeIdx(return_type_idx, resolve);
   }
 
   const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -532,10 +532,10 @@
     return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
   }
 
-  mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
+  mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
-    if (type == NULL) {
+    if (type == NULL && resolve) {
       type = GetClassLinker()->ResolveType(type_idx, method_);
       CHECK(type != NULL || Thread::Current()->IsExceptionPending());
     }
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9a2de47..d2681df 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2129,13 +2129,13 @@
       const RegType* return_type = nullptr;
       if (called_method != nullptr) {
         MethodHelper mh(called_method);
-        mirror::Class* return_type_class = mh.GetReturnType();
+        mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
         if (return_type_class != nullptr) {
           return_type = &reg_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
                                               return_type_class->CannotBeAssignedFromOtherTypes());
         } else {
           Thread* self = Thread::Current();
-          DCHECK(self->IsExceptionPending());
+          DCHECK(!can_load_classes_ || self->IsExceptionPending());
           self->ClearException();
         }
       }
@@ -3518,10 +3518,14 @@
   const RegType* field_type = nullptr;
   if (field != NULL) {
     FieldHelper fh(field);
-    mirror::Class* field_type_class = fh.GetType(false);
+    mirror::Class* field_type_class = fh.GetType(can_load_classes_);
     if (field_type_class != nullptr) {
       field_type = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
                                          field_type_class->CannotBeAssignedFromOtherTypes());
+    } else {
+      Thread* self = Thread::Current();
+      DCHECK(!can_load_classes_ || self->IsExceptionPending());
+      self->ClearException();
     }
   }
   if (field_type == nullptr) {
@@ -3580,10 +3584,14 @@
       return;
     }
     FieldHelper fh(field);
-    mirror::Class* field_type_class = fh.GetType(false);
+    mirror::Class* field_type_class = fh.GetType(can_load_classes_);
     if (field_type_class != nullptr) {
       field_type = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
                                          field_type_class->CannotBeAssignedFromOtherTypes());
+    } else {
+      Thread* self = Thread::Current();
+      DCHECK(!can_load_classes_ || self->IsExceptionPending());
+      self->ClearException();
     }
   }
   if (field_type == nullptr) {
@@ -3673,12 +3681,15 @@
     return;
   }
   FieldHelper fh(field);
-  mirror::Class* field_type_class = fh.GetType(false);
+  mirror::Class* field_type_class = fh.GetType(can_load_classes_);
   const RegType* field_type;
   if (field_type_class != nullptr) {
     field_type = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
                                        field_type_class->CannotBeAssignedFromOtherTypes());
   } else {
+    Thread* self = Thread::Current();
+    DCHECK(!can_load_classes_ || self->IsExceptionPending());
+    self->ClearException();
     field_type = &reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
                                             fh.GetTypeDescriptor(), false);
   }
@@ -3856,13 +3867,13 @@
   if (return_type_ == nullptr) {
     if (mirror_method_ != NULL) {
       MethodHelper mh(mirror_method_);
-      mirror::Class* return_type_class = mh.GetReturnType();
+      mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
       if (return_type_class != nullptr) {
         return_type_ = &reg_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
                                              return_type_class->CannotBeAssignedFromOtherTypes());
       } else {
         Thread* self = Thread::Current();
-        DCHECK(self->IsExceptionPending());
+        DCHECK(!can_load_classes_ || self->IsExceptionPending());
         self->ClearException();
       }
     }