Move MethodHelper::GetReturnType to mirror::ArtMethod.

Also, fix missing handle in HasSameSignatureWithDifferentClassLoaders.

Change-Id: I9e1ffd09be950ecc8346fc3c485760d82d9ecab3
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a6ff530..e4d9baa 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4051,13 +4051,10 @@
   CHECK(prototype->HasSameDexCacheResolvedTypes(method.Get()));
   CHECK_EQ(prototype->GetDexMethodIndex(), method->GetDexMethodIndex());
 
-  StackHandleScope<2> hs(Thread::Current());
-  MethodHelper mh(hs.NewHandle(method.Get()));
-  MethodHelper mh2(hs.NewHandle(prototype.Get()));
   CHECK_STREQ(method->GetName(), prototype->GetName());
   CHECK_STREQ(method->GetShorty(), prototype->GetShorty());
   // More complex sanity - via dex cache
-  CHECK_EQ(mh.GetReturnType(), mh2.GetReturnType());
+  CHECK_EQ(method->GetInterfaceMethodIfProxy()->GetReturnType(), prototype->GetReturnType());
 }
 
 static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics,
@@ -4322,7 +4319,8 @@
     return true;
   }
   // Begin with the methods local to the superclass.
-  StackHandleScope<2> hs(Thread::Current());
+  Thread* self = Thread::Current();
+  StackHandleScope<2> hs(self);
   MutableMethodHelper mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
   MutableMethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
   if (klass->HasSuperClass() &&
@@ -4331,7 +4329,7 @@
       mh.ChangeMethod(klass->GetVTableEntry(i));
       super_mh.ChangeMethod(klass->GetSuperClass()->GetVTableEntry(i));
       if (mh.GetMethod() != super_mh.GetMethod() &&
-          !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
+          !mh.HasSameSignatureWithDifferentClassLoaders(self, &super_mh)) {
         ThrowLinkageError(klass.Get(),
                           "Class %s method %s resolves differently in superclass %s",
                           PrettyDescriptor(klass.Get()).c_str(),
@@ -4348,7 +4346,7 @@
         mh.ChangeMethod(klass->GetIfTable()->GetMethodArray(i)->GetWithoutChecks(j));
         super_mh.ChangeMethod(klass->GetIfTable()->GetInterface(i)->GetVirtualMethod(j));
         if (mh.GetMethod() != super_mh.GetMethod() &&
-            !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) {
+            !mh.HasSameSignatureWithDifferentClassLoaders(self, &super_mh)) {
           ThrowLinkageError(klass.Get(),
                             "Class %s method %s resolves differently in interface %s",
                             PrettyDescriptor(klass.Get()).c_str(),
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 7b90339..da2dfe1 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -218,17 +218,14 @@
   if (o == nullptr) {
     return;
   }
-  mirror::ArtMethod* m = self->GetCurrentMethod(nullptr);
   // Make sure that the result is an instance of the type this method was expected to return.
-  StackHandleScope<1> hs(self);
-  Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
-  mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
+  mirror::Class* return_type = self->GetCurrentMethod(nullptr)->GetReturnType();
 
   if (!o->InstanceOf(return_type)) {
     Runtime::Current()->GetJavaVM()->JniAbortF(nullptr,
                                                "attempt to return an instance of %s from %s",
                                                PrettyTypeOf(o).c_str(),
-                                               PrettyMethod(h_m.Get()).c_str());
+                                               PrettyMethod(self->GetCurrentMethod(nullptr)).c_str());
   }
 }
 
@@ -283,20 +280,19 @@
       return zero;
     } else {
       StackHandleScope<1> hs(soa.Self());
-      MethodHelper mh_interface_method(
+      Handle<mirror::ArtMethod> h_interface_method(
           hs.NewHandle(soa.Decode<mirror::ArtMethod*>(interface_method_jobj)));
       // This can cause thread suspension.
-      mirror::Class* result_type = mh_interface_method.GetReturnType();
+      mirror::Class* result_type = h_interface_method->GetReturnType();
       mirror::Object* result_ref = soa.Decode<mirror::Object*>(result);
       mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj);
       mirror::ArtMethod* proxy_method;
-      if (mh_interface_method.GetMethod()->GetDeclaringClass()->IsInterface()) {
-        proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(
-            mh_interface_method.GetMethod());
+      if (h_interface_method->GetDeclaringClass()->IsInterface()) {
+        proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(h_interface_method.Get());
       } else {
         // Proxy dispatch to a method defined in Object.
-        DCHECK(mh_interface_method.GetMethod()->GetDeclaringClass()->IsObjectClass());
-        proxy_method = mh_interface_method.GetMethod();
+        DCHECK(h_interface_method->GetDeclaringClass()->IsObjectClass());
+        proxy_method = h_interface_method.Get();
       }
       ThrowLocation throw_location(rcvr, proxy_method, -1);
       JValue result_unboxed;
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index b970879..3a177eb 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -321,9 +321,7 @@
     const uint8_t vreg_index = inst->VRegA_11x(inst_data);
     Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
     if (do_assignability_check && obj_result != NULL) {
-      StackHandleScope<1> hs(self);
-      MethodHelper mh(hs.NewHandle(shadow_frame.GetMethod()));
-      Class* return_type = mh.GetReturnType();
+      Class* return_type = shadow_frame.GetMethod()->GetReturnType();
       obj_result = shadow_frame.GetVRegReference(vreg_index);
       if (return_type == NULL) {
         // Return the pending exception.
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 1364ed2..9fb90f1 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -233,9 +233,7 @@
         const size_t ref_idx = inst->VRegA_11x(inst_data);
         Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
         if (do_assignability_check && obj_result != NULL) {
-          StackHandleScope<1> hs(self);
-          MethodHelper mhs(hs.NewHandle(shadow_frame.GetMethod()));
-          Class* return_type = mhs.GetReturnType();
+          Class* return_type = shadow_frame.GetMethod()->GetReturnType();
           // Re-load since it might have moved.
           obj_result = shadow_frame.GetVRegReference(ref_idx);
           if (return_type == NULL) {
diff --git a/runtime/method_helper-inl.h b/runtime/method_helper-inl.h
index fca5cf7..7a7949e 100644
--- a/runtime/method_helper-inl.h
+++ b/runtime/method_helper-inl.h
@@ -57,16 +57,6 @@
   return type;
 }
 
-template <template <class T> class HandleKind>
-inline mirror::Class* MethodHelperT<HandleKind>::GetReturnType(bool resolve) {
-  mirror::ArtMethod* method = GetMethod();
-  const DexFile* dex_file = method->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, resolve);
-}
-
 }  // namespace art
 
 #endif  // ART_RUNTIME_METHOD_HELPER_INL_H_
diff --git a/runtime/method_helper.cc b/runtime/method_helper.cc
index 79c2b91..0799bb0 100644
--- a/runtime/method_helper.cc
+++ b/runtime/method_helper.cc
@@ -39,10 +39,14 @@
 
 template <template <class T> class HandleKind>
 template <template <class T2> class HandleKind2>
-bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders(
+bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders(Thread* self,
     MethodHelperT<HandleKind2>* other) {
-  if (UNLIKELY(GetReturnType() != other->GetReturnType())) {
-    return false;
+  {
+    StackHandleScope<1> hs(self);
+    Handle<mirror::Class> return_type(hs.NewHandle(GetMethod()->GetReturnType()));
+    if (UNLIKELY(other->GetMethod()->GetReturnType() != return_type.Get())) {
+      return false;
+    }
   }
   const DexFile::TypeList* types = method_->GetParameterTypeList();
   const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
@@ -158,19 +162,19 @@
     const DexFile& other_dexfile, uint32_t name_and_signature_idx);
 
 template
-bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>(
+bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
     MethodHelperT<Handle>* other);
 
 template
-bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(
+bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(Thread* self,
     MethodHelperT<MutableHandle>* other);
 
 template
-bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>(
+bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
     MethodHelperT<Handle>* other);
 
 template
 bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(
-    MethodHelperT<MutableHandle>* other);
+    Thread* self, MethodHelperT<MutableHandle>* other);
 
 }  // namespace art
diff --git a/runtime/method_helper.h b/runtime/method_helper.h
index 1458f88..14ba7d1 100644
--- a/runtime/method_helper.h
+++ b/runtime/method_helper.h
@@ -72,10 +72,6 @@
     return refs;
   }
 
-  // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
-  // number of bugs at call sites.
-  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // "1 +" because the first in Args is the receiver.
     // "- 1" because we don't count the return type.
@@ -109,7 +105,7 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   template <template <class T> class HandleKind2>
-  bool HasSameSignatureWithDifferentClassLoaders(MethodHelperT<HandleKind2>* other)
+  bool HasSameSignatureWithDifferentClassLoaders(Thread* self, MethodHelperT<HandleKind2>* other)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index a0b6adf..ca361f8 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -467,6 +467,20 @@
                         new_dex_cache_classes);
 }
 
+inline mirror::Class* ArtMethod::GetReturnType(bool resolve) {
+  DCHECK(!IsProxyMethod());
+  const DexFile* dex_file = GetDexFile();
+  const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
+  const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
+  uint16_t return_type_idx = proto_id.return_type_idx_;
+  mirror::Class* type = GetDexCacheResolvedType(return_type_idx);
+  if (type == nullptr && resolve) {
+    type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this);
+    CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
+  }
+  return type;
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 92b2c30..9bb838b 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -505,6 +505,10 @@
   const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
+  // number of bugs at call sites.
+  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index b57e48f..228d200 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -632,8 +632,8 @@
   }
 
   // Box if necessary and return.
-  return soa.AddLocalReference<jobject>(BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(),
-                                                     result));
+  return soa.AddLocalReference<jobject>(
+      BoxPrimitive(Primitive::GetType(mh.GetMethod()->GetReturnTypeDescriptor()[0]), result));
 }
 
 bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c) {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index fb07ba0..8012451 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2256,8 +2256,7 @@
       if (called_method != nullptr) {
         StackHandleScope<1> hs(self_);
         Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
-        MethodHelper mh(h_called_method);
-        mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
+        mirror::Class* return_type_class = h_called_method->GetReturnType(can_load_classes_);
         if (return_type_class != nullptr) {
           return_type = &reg_types_.FromClass(h_called_method->GetReturnTypeDescriptor(),
                                               return_type_class,
@@ -2301,8 +2300,7 @@
         return_type_descriptor = called_method->GetReturnTypeDescriptor();
         StackHandleScope<1> hs(self_);
         Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
-        MethodHelper mh(h_called_method);
-        mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
+        mirror::Class* return_type_class = h_called_method->GetReturnType(can_load_classes_);
         if (return_type_class != nullptr) {
           return_type = &reg_types_.FromClass(return_type_descriptor,
                                               return_type_class,
@@ -4112,9 +4110,7 @@
 const RegType& MethodVerifier::GetMethodReturnType() {
   if (return_type_ == nullptr) {
     if (mirror_method_.Get() != nullptr) {
-      StackHandleScope<1> hs(self_);
-      mirror::Class* return_type_class =
-          MethodHelper(hs.NewHandle(mirror_method_.Get())).GetReturnType(can_load_classes_);
+      mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_);
       if (return_type_class != nullptr) {
         return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
                                              return_type_class,