Refactor code aroud method resolution.

- Make unresolved AOT entrypoints use the tls cache
- Remove duplicate code
- Inline method access checks logic in its only use.
- Fix in ClassLinker::ResolveMethodWithoutInvokeType() by calling shared
  helper.

Test: test.py
Change-Id: I1f42b5d0ac1dcd9c5eb483db9c5c5eefc9b2f4d1
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 8f3692d..8b6d45d 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -305,129 +305,32 @@
   return resolved;
 }
 
-template <InvokeType type, ClassLinker::ResolveMode kResolveMode>
-inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) {
-  DCHECK(referrer != nullptr);
-  // Note: The referrer can be a Proxy constructor. In that case, we need to do the
-  // lookup in the context of the original method from where it steals the code.
-  // However, we delay the GetInterfaceMethodIfProxy() until needed.
-  DCHECK_IMPLIES(referrer->IsProxyMethod(), referrer->IsConstructor());
-  // We do not need the read barrier for getting the DexCache for the initial resolved method
-  // lookup as both from-space and to-space copies point to the same native resolved methods array.
-  ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
-      method_idx);
-  if (resolved_method == nullptr) {
-    return nullptr;
-  }
-  DCHECK(!resolved_method->IsRuntimeMethod());
-  if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
-    referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
-    // Check if the invoke type matches the class type.
-    ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
-    ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
-    const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx);
-    ObjPtr<mirror::Class> cls = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader);
-    if (cls == nullptr) {
-      // The verifier breaks the invariant that a resolved method must have its
-      // class in the class table. Because this method should only lookup and not
-      // resolve class, return null. The caller is responsible for calling
-      // `ResolveMethod` afterwards.
-      // b/73760543
-      return nullptr;
-    }
-    if (CheckInvokeClassMismatch</* kThrow= */ false>(dex_cache, type, method_idx, class_loader)) {
-      return nullptr;
-    }
-    // Check access.
-    ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
-    if (!referring_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
-                                                  resolved_method,
-                                                  dex_cache,
-                                                  method_idx)) {
-      return nullptr;
-    }
-    // Check if the invoke type matches the method type.
-    if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
-      return nullptr;
-    }
-  }
-  return resolved_method;
-}
-
 template <ClassLinker::ResolveMode kResolveMode>
 inline ArtMethod* ClassLinker::ResolveMethod(Thread* self,
                                              uint32_t method_idx,
                                              ArtMethod* referrer,
                                              InvokeType type) {
   DCHECK(referrer != nullptr);
-  // Note: The referrer can be a Proxy constructor. In that case, we need to do the
-  // lookup in the context of the original method from where it steals the code.
-  // However, we delay the GetInterfaceMethodIfProxy() until needed.
   DCHECK_IMPLIES(referrer->IsProxyMethod(), referrer->IsConstructor());
+
   Thread::PoisonObjectPointersIfDebug();
-  // We do not need the read barrier for getting the DexCache for the initial resolved method
-  // lookup as both from-space and to-space copies point to the same native resolved methods array.
-  ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod(
-      method_idx);
-  DCHECK(resolved_method == nullptr || !resolved_method->IsRuntimeMethod());
-  if (UNLIKELY(resolved_method == nullptr)) {
-    referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
-    ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
-    StackHandleScope<2> hs(self);
-    Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache()));
-    Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
-    resolved_method = ResolveMethod<kResolveMode>(method_idx,
-                                                  h_dex_cache,
-                                                  h_class_loader,
-                                                  referrer,
-                                                  type);
-  } else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
-    referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
-    const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx);
-    ObjPtr<mirror::Class> cls =
-        LookupResolvedType(method_id.class_idx_,
-                           referrer->GetDexCache(),
-                           referrer->GetClassLoader());
-    if (cls == nullptr) {
-      // The verifier breaks the invariant that a resolved method must have its
-      // class in the class table, so resolve the type in case we haven't found it.
-      // b/73760543
-      StackHandleScope<2> hs(Thread::Current());
-      Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache()));
-      Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(referrer->GetClassLoader()));
-      cls = ResolveType(method_id.class_idx_, h_dex_cache, h_class_loader);
-      if (hs.Self()->IsExceptionPending()) {
-        return nullptr;
-      }
-    }
-    // Check if the invoke type matches the class type.
-    if (CheckInvokeClassMismatch</* kThrow= */ true>(
-            referrer->GetDexCache(), type, [cls]() { return cls; })) {
-      DCHECK(Thread::Current()->IsExceptionPending());
-      return nullptr;
-    }
-    // Check access.
-    ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
-    if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(),
-                                                    resolved_method,
-                                                    referrer->GetDexCache(),
-                                                    method_idx,
-                                                    type)) {
-      DCHECK(Thread::Current()->IsExceptionPending());
-      return nullptr;
-    }
-    // Check if the invoke type matches the method type.
-    if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
-      ThrowIncompatibleClassChangeError(type,
-                                        resolved_method->GetInvokeType(),
-                                        resolved_method,
-                                        referrer);
-      return nullptr;
+  // Fast path: no checks and in the dex cache.
+  if (kResolveMode == ResolveMode::kNoChecks) {
+    ArtMethod* resolved_method = referrer->GetDexCache()->GetResolvedMethod(method_idx);
+    if (resolved_method != nullptr) {
+      DCHECK(!resolved_method->IsRuntimeMethod());
+      return resolved_method;
     }
   }
-  // Note: We cannot check here to see whether we added the method to the cache. It
-  //       might be an erroneous class, which results in it being hidden from us.
-  return resolved_method;
+
+  // For a Proxy constructor, we need to do the lookup in the context of the original method
+  // from where it steals the code.
+  referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
+  StackHandleScope<2> hs(self);
+  Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
+  Handle<mirror::ClassLoader> class_loader(
+      hs.NewHandle(referrer->GetDeclaringClass()->GetClassLoader()));
+  return ResolveMethod<kResolveMode>(method_idx, dex_cache, class_loader, referrer, type);
 }
 
 template <ClassLinker::ResolveMode kResolveMode>
@@ -436,10 +339,11 @@
                                              Handle<mirror::ClassLoader> class_loader,
                                              ArtMethod* referrer,
                                              InvokeType type) {
+  DCHECK(dex_cache != nullptr);
   DCHECK(dex_cache->GetClassLoader() == class_loader.Get());
   DCHECK(!Thread::Current()->IsExceptionPending()) << Thread::Current()->GetException()->Dump();
-  DCHECK(dex_cache != nullptr);
   DCHECK(referrer == nullptr || !referrer->IsProxyMethod());
+
   // Check for hit in the dex cache.
   ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
   Thread::PoisonObjectPointersIfDebug();
@@ -499,12 +403,20 @@
   if (kResolveMode == ResolveMode::kCheckICCEAndIAE && resolved != nullptr && referrer != nullptr) {
     ObjPtr<mirror::Class> methods_class = resolved->GetDeclaringClass();
     ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
-    if (!referring_class->CheckResolvedMethodAccess(methods_class,
-                                                    resolved,
-                                                    dex_cache.Get(),
-                                                    method_idx,
-                                                    type)) {
-      DCHECK(Thread::Current()->IsExceptionPending());
+    if (UNLIKELY(!referring_class->CanAccess(methods_class))) {
+      // The referrer class can't access the method's declaring class but may still be able
+      // to access the method if the MethodId specifies an accessible subclass of the declaring
+      // class rather than the declaring class itself.
+      if (UNLIKELY(!referring_class->CanAccess(klass))) {
+        ThrowIllegalAccessErrorClassForMethodDispatch(referring_class,
+                                                      klass,
+                                                      resolved,
+                                                      type);
+        return nullptr;
+      }
+    }
+    if (UNLIKELY(!referring_class->CanAccessMember(methods_class, resolved->GetAccessFlags()))) {
+      ThrowIllegalAccessErrorMethod(referring_class, resolved);
       return nullptr;
     }
   }
@@ -514,23 +426,23 @@
       LIKELY(kResolveMode == ResolveMode::kNoChecks ||
              !resolved->CheckIncompatibleClassChange(type))) {
     return resolved;
-  } else {
-    // If we had a method, or if we can find one with another lookup type,
-    // it's an incompatible-class-change error.
-    if (resolved == nullptr) {
-      resolved = FindIncompatibleMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx);
-    }
-    if (resolved != nullptr) {
-      ThrowIncompatibleClassChangeError(type, resolved->GetInvokeType(), resolved, referrer);
-    } else {
-      // We failed to find the method (using all lookup types), so throw a NoSuchMethodError.
-      const char* name = dex_file.StringDataByIdx(method_id.name_idx_);
-      const Signature signature = dex_file.GetMethodSignature(method_id);
-      ThrowNoSuchMethodError(type, klass, name, signature);
-    }
-    Thread::Current()->AssertPendingException();
-    return nullptr;
   }
+
+  // If we had a method, or if we can find one with another lookup type,
+  // it's an incompatible-class-change error.
+  if (resolved == nullptr) {
+    resolved = FindIncompatibleMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx);
+  }
+  if (resolved != nullptr) {
+    ThrowIncompatibleClassChangeError(type, resolved->GetInvokeType(), resolved, referrer);
+  } else {
+    // We failed to find the method (using all lookup types), so throw a NoSuchMethodError.
+    const char* name = dex_file.StringDataByIdx(method_id.name_idx_);
+    const Signature signature = dex_file.GetMethodSignature(method_id);
+    ThrowNoSuchMethodError(type, klass, name, signature);
+  }
+  Thread::Current()->AssertPendingException();
+  return nullptr;
 }
 
 inline ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx,
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e109a50..8082d46 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -9471,19 +9471,7 @@
     Thread::Current()->AssertPendingException();
     return nullptr;
   }
-  if (klass->IsInterface()) {
-    resolved = klass->FindInterfaceMethod(dex_cache.Get(), method_idx, image_pointer_size_);
-  } else {
-    resolved = klass->FindClassMethod(dex_cache.Get(), method_idx, image_pointer_size_);
-  }
-  if (resolved != nullptr &&
-      hiddenapi::ShouldDenyAccessToMember(
-          resolved,
-          hiddenapi::AccessContext(class_loader.Get(), dex_cache.Get()),
-          hiddenapi::AccessMethod::kLinking)) {
-    resolved = nullptr;
-  }
-  return resolved;
+  return FindResolvedMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx);
 }
 
 ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index b7a05ee..9a57bd4 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -367,14 +367,11 @@
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
 
-  template <InvokeType type, ResolveMode kResolveMode>
-  ArtMethod* GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-
   template <ResolveMode kResolveMode>
   ArtMethod* ResolveMethod(Thread* self, uint32_t method_idx, ArtMethod* referrer, InvokeType type)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
+
   ArtMethod* ResolveMethodWithoutInvokeType(uint32_t method_idx,
                                             Handle<mirror::DexCache> dex_cache,
                                             Handle<mirror::ClassLoader> class_loader)
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 91163f4..cbe7543 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -519,6 +519,7 @@
                             ArtMethod* caller,
                             ObjPtr<mirror::Object>* this_object,
                             const Instruction& inst,
+                            bool only_lookup_tls_cache,
                             /*out*/ bool* string_init)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
@@ -526,6 +527,9 @@
   // Try to find the method in thread-local cache.
   size_t tls_value = 0u;
   if (!self->GetInterpreterCache()->Get(self, &inst, &tls_value)) {
+    if (only_lookup_tls_cache) {
+      return nullptr;
+    }
     DCHECK(!self->IsExceptionPending());
     // NterpGetMethod can suspend, so save this_object.
     StackHandleScope<1> hs(self);
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 777fd98..a69b055 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -148,6 +148,7 @@
                                    ArtMethod* referrer,
                                    ObjPtr<mirror::Object>* this_object,
                                    const Instruction& inst,
+                                   bool only_lookup_tls_cache,
                                    /*out*/ bool* string_init)
     REQUIRES_SHARED(Locks::mutator_lock_)
     REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 559662c..4960f38 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2079,68 +2079,6 @@
   return GenericJniMethodEnd(self, cookie, result, result_f, called);
 }
 
-// Fast path method resolution that can't throw exceptions.
-template <InvokeType type>
-inline ArtMethod* FindMethodFast(uint32_t method_idx,
-                                 ObjPtr<mirror::Object> this_object,
-                                 ArtMethod* referrer)
-    REQUIRES_SHARED(Locks::mutator_lock_)
-    REQUIRES(!Roles::uninterruptible_) {
-  ScopedAssertNoThreadSuspension ants(__FUNCTION__);
-  if (UNLIKELY(this_object == nullptr && type != kStatic)) {
-    return nullptr;
-  }
-  ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
-  ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
-  constexpr ClassLinker::ResolveMode resolve_mode = ClassLinker::ResolveMode::kCheckICCEAndIAE;
-  ClassLinker* linker = Runtime::Current()->GetClassLinker();
-  ArtMethod* resolved_method = linker->GetResolvedMethod<type, resolve_mode>(method_idx, referrer);
-  if (UNLIKELY(resolved_method == nullptr)) {
-    return nullptr;
-  }
-  if (type == kInterface) {  // Most common form of slow path dispatch.
-    return this_object->GetClass()->FindVirtualMethodForInterface(resolved_method,
-                                                                  kRuntimePointerSize);
-  }
-  if (type == kStatic || type == kDirect) {
-    return resolved_method;
-  }
-
-  if (type == kSuper) {
-    // TODO This lookup is rather slow.
-    dex::TypeIndex method_type_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
-    ObjPtr<mirror::Class> method_reference_class = linker->LookupResolvedType(
-        method_type_idx, dex_cache, referrer->GetClassLoader());
-    if (method_reference_class == nullptr) {
-      // Need to do full type resolution...
-      return nullptr;
-    }
-
-    // If the referring class is in the class hierarchy of the
-    // referenced class in the bytecode, we use its super class. Otherwise, we cannot
-    // resolve the method.
-    if (!method_reference_class->IsAssignableFrom(referring_class)) {
-      return nullptr;
-    }
-
-    if (method_reference_class->IsInterface()) {
-      return method_reference_class->FindVirtualMethodForInterfaceSuper(
-          resolved_method, kRuntimePointerSize);
-    }
-
-    ObjPtr<mirror::Class> super_class = referring_class->GetSuperClass();
-    if (resolved_method->GetMethodIndex() >= super_class->GetVTableLength()) {
-      // The super class does not have the method.
-      return nullptr;
-    }
-    return super_class->GetVTableEntry(resolved_method->GetMethodIndex(), kRuntimePointerSize);
-  }
-
-  DCHECK(type == kVirtual);
-  return this_object->GetClass()->GetVTableEntry(
-      resolved_method->GetMethodIndex(), kRuntimePointerSize);
-}
-
 // We use TwoWordReturn to optimize scalar returns. We use the hi value for code, and the lo value
 // for the method pointer.
 //
@@ -2155,8 +2093,19 @@
   ScopedQuickEntrypointChecks sqec(self);
   DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs));
   ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp);
-  ArtMethod* method = FindMethodFast<type>(method_idx, this_object, caller_method);
+  uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
+  CodeItemInstructionAccessor accessor(caller_method->DexInstructions());
+  DCHECK_LT(dex_pc, accessor.InsnsSizeInCodeUnits());
+  const Instruction& instr = accessor.InstructionAt(dex_pc);
+  bool string_init = false;
+  ArtMethod* method = FindMethodToCall<type>(
+      self, caller_method, &this_object, instr, /* only_lookup_tls_cache= */ true, &string_init);
+
   if (UNLIKELY(method == nullptr)) {
+    if (self->IsExceptionPending()) {
+      // Return a failure if the first lookup threw an exception.
+      return GetTwoWordFailureValue();  // Failure.
+    }
     const DexFile* dex_file = caller_method->GetDexFile();
     uint32_t shorty_len;
     const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx), &shorty_len);
@@ -2166,12 +2115,12 @@
       RememberForGcArgumentVisitor visitor(sp, type == kStatic, shorty, shorty_len, &soa);
       visitor.VisitArguments();
 
-      uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
-      CodeItemInstructionAccessor accessor(caller_method->DexInstructions());
-      CHECK_LT(dex_pc, accessor.InsnsSizeInCodeUnits());
-      const Instruction& instr = accessor.InstructionAt(dex_pc);
-      bool string_init = false;
-      method = FindMethodToCall<type>(self, caller_method, &this_object, instr, &string_init);
+      method = FindMethodToCall<type>(self,
+                                      caller_method,
+                                      &this_object,
+                                      instr,
+                                      /* only_lookup_tls_cache= */ false,
+                                      &string_init);
 
       visitor.FixupReferences();
     }
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 64d4d71..35e329c 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -239,7 +239,8 @@
   ObjPtr<mirror::Object> obj = type == kStatic ? nullptr : shadow_frame.GetVRegReference(vregC);
   ArtMethod* sf_method = shadow_frame.GetMethod();
   bool string_init = false;
-  ArtMethod* called_method = FindMethodToCall<type>(self, sf_method, &obj, *inst, &string_init);
+  ArtMethod* called_method = FindMethodToCall<type>(
+      self, sf_method, &obj, *inst, /* only_lookup_tls_cache= */ false, &string_init);
   if (called_method == nullptr) {
     DCHECK(self->IsExceptionPending());
     result->SetJ(0);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 77f78c5..b6b1415 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -498,47 +498,6 @@
   return false;
 }
 
-template <bool throw_on_failure>
-inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
-                                            ArtMethod* method,
-                                            ObjPtr<DexCache> dex_cache,
-                                            uint32_t method_idx,
-                                            InvokeType throw_invoke_type) {
-  DCHECK(throw_on_failure || throw_invoke_type == kStatic);
-  DCHECK(dex_cache != nullptr);
-  if (UNLIKELY(!this->CanAccess(access_to))) {
-    // The referrer class can't access the method's declaring class but may still be able
-    // to access the method if the MethodId specifies an accessible subclass of the declaring
-    // class rather than the declaring class itself.
-    dex::TypeIndex class_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
-    // The referenced class has already been resolved with the method, but may not be in the dex
-    // cache.
-    ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
-        class_idx,
-        dex_cache,
-        GetClassLoader());
-    DCHECK(dex_access_to != nullptr)
-        << " Could not resolve " << dex_cache->GetDexFile()->StringByTypeIdx(class_idx)
-        << " when checking access to " << method->PrettyMethod() << " from " << PrettyDescriptor();
-    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
-      if (throw_on_failure) {
-        ThrowIllegalAccessErrorClassForMethodDispatch(this,
-                                                      dex_access_to,
-                                                      method,
-                                                      throw_invoke_type);
-      }
-      return false;
-    }
-  }
-  if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
-    return true;
-  }
-  if (throw_on_failure) {
-    ThrowIllegalAccessErrorMethod(this, method);
-  }
-  return false;
-}
-
 inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
                                           ArtField* field,
                                           ObjPtr<DexCache> dex_cache,
@@ -553,22 +512,6 @@
   return ResolvedFieldAccessTest<true>(access_to, field, dex_cache, field_idx);
 }
 
-inline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to,
-                                           ArtMethod* method,
-                                           ObjPtr<DexCache> dex_cache,
-                                           uint32_t method_idx) {
-  return ResolvedMethodAccessTest<false>(access_to, method, dex_cache, method_idx, kStatic);
-}
-
-inline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to,
-                                             ArtMethod* method,
-                                             ObjPtr<DexCache> dex_cache,
-                                             uint32_t method_idx,
-                                             InvokeType throw_invoke_type) {
-  return ResolvedMethodAccessTest<true>(
-      access_to, method, dex_cache, method_idx, throw_invoke_type);
-}
-
 inline bool Class::IsObsoleteVersionOf(ObjPtr<Class> klass) {
   DCHECK(!klass->IsObsoleteObject()) << klass->PrettyClass() << " is obsolete!";
   if (LIKELY(!IsObsoleteObject())) {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 67b9559..ca13462 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -638,21 +638,6 @@
                                 uint32_t field_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  // Can this class access a resolved method?
-  // Note that access to methods's class is checked and this may require looking up the class
-  // referenced by the MethodId in the DexFile in case the declaring class is inaccessible.
-  bool CanAccessResolvedMethod(ObjPtr<Class> access_to,
-                               ArtMethod* resolved_method,
-                               ObjPtr<DexCache> dex_cache,
-                               uint32_t method_idx)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-  bool CheckResolvedMethodAccess(ObjPtr<Class> access_to,
-                                 ArtMethod* resolved_method,
-                                 ObjPtr<DexCache> dex_cache,
-                                 uint32_t method_idx,
-                                 InvokeType throw_invoke_type)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-
   bool IsSubClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Can src be assigned to this class? For example, String can be assigned to Object (by an
@@ -1391,14 +1376,6 @@
                                uint32_t field_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  template <bool throw_on_failure>
-  bool ResolvedMethodAccessTest(ObjPtr<Class> access_to,
-                                ArtMethod* resolved_method,
-                                ObjPtr<DexCache> dex_cache,
-                                uint32_t method_idx,
-                                InvokeType throw_invoke_type)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-
   bool IsArrayAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);