Use virtual dispatch for `MethodHandle.asType()`.

The non-virtual dispatch was a mistake in
    https://android-review.googlesource.com/1944906 .

Change well known method handle methods to `ArtMethod*`.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: atest CtsLibcoreTestCases
Change-Id: I3670ca6a229942e2edbd351a922f83f5d20d0c09
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 919383f..6480dfd 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1144,6 +1144,8 @@
       // Ensure `Thread` and `ThreadGroup` classes are initialized (avoid check at runtime).
       WellKnownClasses::java_lang_Thread_init,
       WellKnownClasses::java_lang_ThreadGroup_add,
+      // Ensure `MethodHandles` class is initialized (avoid check at runtime).
+      WellKnownClasses::java_lang_invoke_MethodHandles_lookup,
       // Ensure `DirectByteBuffer` class is initialized (avoid check at runtime).
       WellKnownClasses::java_nio_DirectByteBuffer_init,
       // Ensure reflection annotation classes are initialized (avoid check at runtime).
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 73ec31e..a992af0 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -864,19 +864,13 @@
   if (atc == nullptr || !callsite_type->IsExactMatch(atc->GetMethodType())) {
     // Cached asType adapter does not exist or is for another call site. Call
     // MethodHandle::asType() to get an appropriate adapter.
-    ArtMethod* as_type =
-        jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_asType);
-    uint32_t as_type_args[] = {
-        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_handle.Get())),
-        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(callsite_type.Get()))};
-    JValue atc_result;
-    as_type->Invoke(self, as_type_args, sizeof(as_type_args), &atc_result, "LL");
-    if (atc_result.GetL() == nullptr) {
+    ArtMethod* as_type = WellKnownClasses::java_lang_invoke_MethodHandle_asType;
+    ObjPtr<mirror::MethodHandle> atc_method_handle = ObjPtr<mirror::MethodHandle>::DownCast(
+        as_type->InvokeVirtual<'L', 'L'>(self, method_handle.Get(), callsite_type.Get()));
+    if (atc_method_handle == nullptr) {
       DCHECK(self->IsExceptionPending());
       return false;
     }
-    ObjPtr<mirror::MethodHandle> atc_method_handle =
-        down_cast<mirror::MethodHandle*>(atc_result.GetL());
     atc.Assign(atc_method_handle);
     DCHECK(!atc.IsNull());
   }
@@ -917,8 +911,7 @@
   const uint16_t num_vregs = callsite_type->NumberOfVRegs();
 
   const char* old_cause = self->StartAssertNoThreadSuspension("EmulatedStackFrame to ShadowFrame");
-  ArtMethod* invoke_exact =
-      jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact);
+  ArtMethod* invoke_exact = WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact;
   ShadowFrameAllocaUniquePtr shadow_frame =
       CREATE_SHADOW_FRAME(num_vregs, invoke_exact, /*dex_pc*/ 0);
   emulated_frame->WriteToShadowFrame(self, callsite_type, 0, shadow_frame.get());
diff --git a/runtime/mirror/method_handles_lookup.cc b/runtime/mirror/method_handles_lookup.cc
index e9c41f9..c4c2b58 100644
--- a/runtime/mirror/method_handles_lookup.cc
+++ b/runtime/mirror/method_handles_lookup.cc
@@ -20,7 +20,6 @@
 #include "class_root-inl.h"
 #include "dex/modifiers.h"
 #include "handle_scope.h"
-#include "jni/jni_internal.h"
 #include "mirror/method_handle_impl.h"
 #include "obj_ptr-inl.h"
 #include "object-inl.h"
@@ -42,25 +41,18 @@
 }
 
 ObjPtr<MethodHandlesLookup> MethodHandlesLookup::GetDefault(Thread* const self) {
-  ArtMethod* lookup = jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandles_lookup);
-  JValue result;
-  lookup->Invoke(self, nullptr, 0, &result, "L");
-  return ObjPtr<MethodHandlesLookup>::DownCast(result.GetL());
+  ArtMethod* lookup = WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
+  DCHECK(lookup->GetDeclaringClass()->IsInitialized());
+  return ObjPtr<MethodHandlesLookup>::DownCast(lookup->InvokeStatic<'L'>(self));
 }
 
 ObjPtr<MethodHandle> MethodHandlesLookup::FindConstructor(Thread* const self,
                                                           Handle<Class> klass,
                                                           Handle<MethodType> method_type) {
-  ArtMethod* findConstructor =
-      jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor);
-  uint32_t args[] = {
-    static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this)),
-    static_cast<uint32_t>(reinterpret_cast<uintptr_t>(klass.Get())),
-    static_cast<uint32_t>(reinterpret_cast<uintptr_t>(method_type.Get()))
-  };
-  JValue result;
-  findConstructor->Invoke(self, args, sizeof(args), &result, "LLL");
-  return ObjPtr<MethodHandle>::DownCast(result.GetL());
+  ArtMethod* find_constructor =
+      WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
+  return ObjPtr<MethodHandle>::DownCast(
+      find_constructor->InvokeFinal<'L', 'L', 'L'>(self, this, klass.Get(), method_type.Get()));
 }
 
 }  // namespace mirror
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 9f1b8e7..a30d2d0 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -95,10 +95,10 @@
 ArtMethod* WellKnownClasses::java_lang_Float_floatToRawIntBits;
 ArtMethod* WellKnownClasses::java_lang_Float_valueOf;
 ArtMethod* WellKnownClasses::java_lang_Integer_valueOf;
-jmethodID WellKnownClasses::java_lang_invoke_MethodHandle_asType;
-jmethodID WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact;
-jmethodID WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
-jmethodID WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_asType;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
+ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
 ArtMethod* WellKnownClasses::java_lang_Long_valueOf;
 jmethodID WellKnownClasses::java_lang_ref_FinalizerReference_add;
 jmethodID WellKnownClasses::java_lang_ref_ReferenceQueue_add;
@@ -430,10 +430,6 @@
   java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V");
   java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V");
   java_lang_Daemons_waitForDaemonStart = CacheMethod(env, java_lang_Daemons, true, "waitForDaemonStart", "()V");
-  java_lang_invoke_MethodHandle_asType = CacheMethod(env, "java/lang/invoke/MethodHandle", false, "asType", "(Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;");
-  java_lang_invoke_MethodHandle_invokeExact = CacheMethod(env, "java/lang/invoke/MethodHandle", false, "invokeExact", "([Ljava/lang/Object;)Ljava/lang/Object;");
-  java_lang_invoke_MethodHandles_lookup = CacheMethod(env, "java/lang/invoke/MethodHandles", true, "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;");
-  java_lang_invoke_MethodHandles_Lookup_findConstructor = CacheMethod(env, "java/lang/invoke/MethodHandles$Lookup", false, "findConstructor", "(Ljava/lang/Class;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;");
 
   java_lang_ref_FinalizerReference_add = CacheMethod(env, "java/lang/ref/FinalizerReference", true, "add", "(Ljava/lang/Object;)V");
   java_lang_ref_ReferenceQueue_add = CacheMethod(env, "java/lang/ref/ReferenceQueue", true, "add", "(Ljava/lang/ref/Reference;)V");
@@ -442,7 +438,7 @@
   java_lang_reflect_Parameter_init = CacheMethod(env, java_lang_reflect_Parameter, false, "<init>", "(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V");
   java_lang_String_charAt = CacheMethod(env, java_lang_String, false, "charAt", "(I)C");
 
-  StackHandleScope<14u> hs(self);
+  StackHandleScope<17u> hs(self);
   Handle<mirror::Class> d_s_vmr =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/VMRuntime;"));
   Handle<mirror::Class> j_i_fd =
@@ -451,6 +447,12 @@
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Thread;"));
   Handle<mirror::Class> j_l_tg =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ThreadGroup;"));
+  Handle<mirror::Class> j_l_i_MethodHandle =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/invoke/MethodHandle;"));
+  Handle<mirror::Class> j_l_i_MethodHandles =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/invoke/MethodHandles;"));
+  Handle<mirror::Class> j_l_i_MethodHandles_Lookup =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/invoke/MethodHandles$Lookup;"));
   Handle<mirror::Class> j_n_b =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/nio/Buffer;"));
   Handle<mirror::Class> j_n_bb =
@@ -512,6 +514,31 @@
       "(Ljava/lang/Thread;)V",
       pointer_size);
 
+  java_lang_invoke_MethodHandle_asType = CacheMethod(
+      j_l_i_MethodHandle.Get(),
+      /*is_static=*/ false,
+      "asType",
+      "(Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;",
+      pointer_size);
+  java_lang_invoke_MethodHandle_invokeExact = CacheMethod(
+      j_l_i_MethodHandle.Get(),
+      /*is_static=*/ false,
+      "invokeExact",
+      "([Ljava/lang/Object;)Ljava/lang/Object;",
+      pointer_size);
+  java_lang_invoke_MethodHandles_lookup = CacheMethod(
+      j_l_i_MethodHandles.Get(),
+      /*is_static=*/ true,
+      "lookup",
+      "()Ljava/lang/invoke/MethodHandles$Lookup;",
+      pointer_size);
+  java_lang_invoke_MethodHandles_Lookup_findConstructor = CacheMethod(
+      j_l_i_MethodHandles_Lookup.Get(),
+      /*is_static=*/ false,
+      "findConstructor",
+      "(Ljava/lang/Class;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;",
+      pointer_size);
+
   java_nio_Buffer_isDirect =
       CacheMethod(j_n_b.Get(), /*is_static=*/ false, "isDirect", "()Z", pointer_size);
   java_nio_DirectByteBuffer_init =
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 0a58766..1f5b03f 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -106,10 +106,10 @@
   static ArtMethod* java_lang_Float_floatToRawIntBits;
   static ArtMethod* java_lang_Float_valueOf;
   static ArtMethod* java_lang_Integer_valueOf;
-  static jmethodID java_lang_invoke_MethodHandle_asType;
-  static jmethodID java_lang_invoke_MethodHandle_invokeExact;
-  static jmethodID java_lang_invoke_MethodHandles_lookup;
-  static jmethodID java_lang_invoke_MethodHandles_Lookup_findConstructor;
+  static ArtMethod* java_lang_invoke_MethodHandle_asType;
+  static ArtMethod* java_lang_invoke_MethodHandle_invokeExact;
+  static ArtMethod* java_lang_invoke_MethodHandles_lookup;
+  static ArtMethod* java_lang_invoke_MethodHandles_Lookup_findConstructor;
   static ArtMethod* java_lang_Long_valueOf;
   static jmethodID java_lang_ref_FinalizerReference_add;
   static jmethodID java_lang_ref_ReferenceQueue_add;