Partial revert of "Reduce using ArtMethod's dex_cache_resolved_types_."

Change Ic45a5ff8c66b79429e440cbc08d67bf22a083682 made the resolution
from true to false, assuming we could only enter that specific code
with a resolved type. Unfortunately b/34440020 shows we still
need to resolve.

Also move arg to a Handle, now that we are resolving, which could
lead to thread suspension.

bug:34440020
bug:34452336
Test: test-art-host test-art-target
Change-Id: I98c834158733a46cf896e7dfa7ce226c53e2d949
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 75176f9..a2b4cb3 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -216,43 +216,54 @@
   }
 
   bool BuildArgArrayFromObjectArray(ObjPtr<mirror::Object> receiver,
-                                    ObjPtr<mirror::ObjectArray<mirror::Object>> args,
-                                    ArtMethod* m)
+                                    ObjPtr<mirror::ObjectArray<mirror::Object>> raw_args,
+                                    ArtMethod* m,
+                                    Thread* self)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     const DexFile::TypeList* classes = m->GetParameterTypeList();
     // Set receiver if non-null (method is not static)
     if (receiver != nullptr) {
       Append(receiver);
     }
+    StackHandleScope<2> hs(self);
+    MutableHandle<mirror::Object> arg(hs.NewHandle<mirror::Object>(nullptr));
+    Handle<mirror::ObjectArray<mirror::Object>> args(
+        hs.NewHandle<mirror::ObjectArray<mirror::Object>>(raw_args));
     for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) {
-      ObjPtr<mirror::Object> arg(args->Get(args_offset));
-      if (((shorty_[i] == 'L') && (arg != nullptr)) || ((arg == nullptr && shorty_[i] != 'L'))) {
-        // Note: The method's parameter's type must have been previously resolved.
+      arg.Assign(args->Get(args_offset));
+      if (((shorty_[i] == 'L') && (arg.Get() != nullptr)) ||
+          ((arg.Get() == nullptr && shorty_[i] != 'L'))) {
+        // TODO: The method's parameter's type must have been previously resolved, yet
+        // we've seen cases where it's not b/34440020.
         ObjPtr<mirror::Class> dst_class(
             m->GetClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_,
-                                     false /* resolve */));
-        DCHECK(dst_class != nullptr) << m->PrettyMethod() << " arg #" << i;
-        if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) {
+                                     true /* resolve */));
+        if (dst_class.Ptr() == nullptr) {
+          CHECK(self->IsExceptionPending());
+          return false;
+        }
+        if (UNLIKELY(arg.Get() == nullptr || !arg->InstanceOf(dst_class))) {
           ThrowIllegalArgumentException(
               StringPrintf("method %s argument %zd has type %s, got %s",
                   m->PrettyMethod(false).c_str(),
                   args_offset + 1,  // Humans don't count from 0.
                   mirror::Class::PrettyDescriptor(dst_class).c_str(),
-                  mirror::Object::PrettyTypeOf(arg).c_str()).c_str());
+                  mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str());
           return false;
         }
       }
 
 #define DO_FIRST_ARG(match_descriptor, get_fn, append) { \
-          if (LIKELY(arg != nullptr && arg->GetClass()->DescriptorEquals(match_descriptor))) { \
+          if (LIKELY(arg.Get() != nullptr && \
+              arg->GetClass()->DescriptorEquals(match_descriptor))) { \
             ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
-            append(primitive_field-> get_fn(arg));
+            append(primitive_field-> get_fn(arg.Get()));
 
 #define DO_ARG(match_descriptor, get_fn, append) \
-          } else if (LIKELY(arg != nullptr && \
+          } else if (LIKELY(arg.Get() != nullptr && \
                             arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
             ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
-            append(primitive_field-> get_fn(arg));
+            append(primitive_field-> get_fn(arg.Get()));
 
 #define DO_FAIL(expected) \
           } else { \
@@ -266,14 +277,14 @@
                       ArtMethod::PrettyMethod(m, false).c_str(), \
                       args_offset + 1, \
                       expected, \
-                      mirror::Object::PrettyTypeOf(arg).c_str()).c_str()); \
+                      mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str()); \
             } \
             return false; \
           } }
 
       switch (shorty_[i]) {
         case 'L':
-          Append(arg);
+          Append(arg.Get());
           break;
         case 'Z':
           DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append)
@@ -646,7 +657,7 @@
   uint32_t shorty_len = 0;
   const char* shorty = np_method->GetShorty(&shorty_len);
   ArgArray arg_array(shorty, shorty_len);
-  if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method)) {
+  if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method, soa.Self())) {
     CHECK(soa.Self()->IsExceptionPending());
     return nullptr;
   }