ART: Compiler support for const-method-handle

Implemented as a runtime call.

Bug: 66890674
Test: art/test.py --target -r -t 979
Test: art/test.py --target --64 -r -t 979
Test: art/test.py --host -r -t 979
Change-Id: I67f461c819a7d528d7455afda8b4a59e9aed381c
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index df184bc..a58946a 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -260,6 +260,13 @@
   return DoGetCalleeSaveMethodOuterCallerAndPc(sp, type).first;
 }
 
+ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer,
+                                                         uint32_t method_handle_idx) {
+  Thread::PoisonObjectPointersIfDebug();
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  return class_linker->ResolveMethodHandle(Thread::Current(), method_handle_idx, referrer);
+}
+
 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer,
                                                      uint32_t proto_idx) {
   Thread::PoisonObjectPointersIfDebug();
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 203ff3d..0a3b5df 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -34,6 +34,7 @@
 namespace mirror {
 class Array;
 class Class;
+class MethodHandle;
 class MethodType;
 class Object;
 class String;
@@ -152,6 +153,11 @@
     REQUIRES_SHARED(Locks::mutator_lock_)
     REQUIRES(!Roles::uninterruptible_);
 
+ObjPtr<mirror::MethodHandle> ResolveMethodHandleFromCode(ArtMethod* referrer,
+                                                         uint32_t method_handle_idx)
+    REQUIRES_SHARED(Locks::mutator_lock_)
+    REQUIRES(!Roles::uninterruptible_);
+
 ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, uint32_t proto_idx)
     REQUIRES_SHARED(Locks::mutator_lock_)
     REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/entrypoints/quick/quick_default_externs.h b/runtime/entrypoints/quick/quick_default_externs.h
index d934a53..1804d9e 100644
--- a/runtime/entrypoints/quick/quick_default_externs.h
+++ b/runtime/entrypoints/quick/quick_default_externs.h
@@ -37,6 +37,7 @@
 extern "C" void* art_quick_initialize_static_storage(uint32_t);
 extern "C" void* art_quick_initialize_type(uint32_t);
 extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t);
+extern "C" void* art_quick_resolve_method_handle(uint32_t);
 extern "C" void* art_quick_resolve_method_type(uint32_t);
 extern "C" void* art_quick_resolve_string(uint32_t);
 
diff --git a/runtime/entrypoints/quick/quick_default_init_entrypoints.h b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
index a4572f6..3f66045 100644
--- a/runtime/entrypoints/quick/quick_default_init_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
@@ -37,6 +37,7 @@
   qpoints->pInitializeStaticStorage = art_quick_initialize_static_storage;
   qpoints->pInitializeTypeAndVerifyAccess = art_quick_initialize_type_and_verify_access;
   qpoints->pInitializeType = art_quick_initialize_type;
+  qpoints->pResolveMethodHandle = art_quick_resolve_method_handle;
   qpoints->pResolveMethodType = art_quick_resolve_method_type;
   qpoints->pResolveString = art_quick_resolve_string;
 
diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index 09cbfff..cf9ddd8 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -183,6 +183,17 @@
   return result.Ptr();
 }
 
+extern "C" mirror::MethodHandle* artResolveMethodHandleFromCode(uint32_t method_handle_idx,
+                                                                Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  ScopedQuickEntrypointChecks sqec(self);
+  auto caller_and_outer =
+      GetCalleeSaveMethodCallerAndOuterMethod(self, CalleeSaveType::kSaveEverything);
+  ArtMethod* caller = caller_and_outer.caller;
+  ObjPtr<mirror::MethodHandle> result = ResolveMethodHandleFromCode(caller, method_handle_idx);
+  return result.Ptr();
+}
+
 extern "C" mirror::MethodType* artResolveMethodTypeFromCode(uint32_t proto_idx, Thread* self)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   ScopedQuickEntrypointChecks sqec(self);
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
index 39dcd39..3a8faca 100644
--- a/runtime/entrypoints/quick/quick_entrypoints_list.h
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -38,6 +38,7 @@
   V(InitializeStaticStorage, void*, uint32_t) \
   V(InitializeTypeAndVerifyAccess, void*, uint32_t) \
   V(InitializeType, void*, uint32_t) \
+  V(ResolveMethodHandle, void*, uint32_t) \
   V(ResolveMethodType, void*, uint32_t) \
   V(ResolveString, void*, uint32_t) \
 \