Small refactoring of field/method access checks.

And some cleanup to reduce the size of the upcoming
method resolution rewrite CL.

Test: m test-art-host
Test: testrunner.py --host
Test: testrunner.py --host --interp-ac
Bug: 62855082
Change-Id: I5bbf0a92d75fe9de6982b80280cd5877fcc37700
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index a04349e..db95bd6 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -103,16 +103,16 @@
 }
 
 inline ArtMethod* CompilerDriver::ResolveMethod(
-    ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
-    Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
-    uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) {
+    ScopedObjectAccess& soa,
+    Handle<mirror::DexCache> dex_cache,
+    Handle<mirror::ClassLoader> class_loader,
+    const DexCompilationUnit* mUnit,
+    uint32_t method_idx,
+    InvokeType invoke_type) {
   DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
   ArtMethod* resolved_method =
-      check_incompatible_class_change
-          ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>(
-              *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type)
-          : mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
-              *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type);
+      mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>(
+          *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type);
   if (UNLIKELY(resolved_method == nullptr)) {
     DCHECK(soa.Self()->IsExceptionPending());
     // Clean up any exception left by type resolution.
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index cd4f400..e9e7378 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -254,9 +254,12 @@
 
   // Resolve a method. Returns null on failure, including incompatible class change.
   ArtMethod* ResolveMethod(
-      ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
-      Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
-      uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
+      ScopedObjectAccess& soa,
+      Handle<mirror::DexCache> dex_cache,
+      Handle<mirror::ClassLoader> class_loader,
+      const DexCompilationUnit* mUnit,
+      uint32_t method_idx,
+      InvokeType invoke_type)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   void ProcessedInstanceField(bool resolved);
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 37734e8..6547299 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -376,6 +376,7 @@
     mirror::Class* referring_class = referrer->GetDeclaringClass();
     if (UNLIKELY(!referring_class->CheckResolvedFieldAccess(fields_class,
                                                             resolved_field,
+                                                            referrer->GetDexCache(),
                                                             field_idx))) {
       DCHECK(self->IsExceptionPending());  // Throw exception and unwind.
       return nullptr;  // Failure.
@@ -461,9 +462,11 @@
   } else if (access_check) {
     mirror::Class* methods_class = resolved_method->GetDeclaringClass();
     bool can_access_resolved_method =
-        referrer->GetDeclaringClass()->CheckResolvedMethodAccess<type>(methods_class,
-                                                                       resolved_method,
-                                                                       method_idx);
+        referrer->GetDeclaringClass()->CheckResolvedMethodAccess(methods_class,
+                                                                 resolved_method,
+                                                                 referrer->GetDexCache(),
+                                                                 method_idx,
+                                                                 type);
     if (UNLIKELY(!can_access_resolved_method)) {
       DCHECK(self->IsExceptionPending());  // Throw exception and unwind.
       return nullptr;  // Failure.
@@ -662,7 +665,7 @@
       return nullptr;
     }
   }
-  mirror::Class* referring_class = referrer->GetDeclaringClass();
+  ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
   if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
                !referring_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) ||
                (is_set && resolved_field->IsFinal() && (fields_class != referring_class)))) {
@@ -677,18 +680,17 @@
 }
 
 // Fast path method resolution that can't throw exceptions.
+template <InvokeType type, bool access_check>
 inline ArtMethod* FindMethodFast(uint32_t method_idx,
                                  ObjPtr<mirror::Object> this_object,
-                                 ArtMethod* referrer,
-                                 bool access_check,
-                                 InvokeType type) {
+                                 ArtMethod* referrer) {
   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
   if (UNLIKELY(this_object == nullptr && type != kStatic)) {
     return nullptr;
   }
-  mirror::Class* referring_class = referrer->GetDeclaringClass();
-  ArtMethod* resolved_method =
-      referrer->GetDexCache()->GetResolvedMethod(method_idx, kRuntimePointerSize);
+  ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
+  ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
+  ArtMethod* resolved_method = dex_cache->GetResolvedMethod(method_idx, kRuntimePointerSize);
   if (UNLIKELY(resolved_method == nullptr)) {
     return nullptr;
   }
@@ -698,7 +700,7 @@
     if (UNLIKELY(icce)) {
       return nullptr;
     }
-    mirror::Class* methods_class = resolved_method->GetDeclaringClass();
+    ObjPtr<mirror::Class> methods_class = resolved_method->GetDeclaringClass();
     if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
                  !referring_class->CanAccessMember(methods_class,
                                                    resolved_method->GetAccessFlags()))) {
@@ -713,7 +715,6 @@
     return resolved_method;
   } else if (type == kSuper) {
     // TODO This lookup is rather slow.
-    ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
     dex::TypeIndex method_type_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
     ObjPtr<mirror::Class> method_reference_class = ClassLinker::LookupResolvedType(
         method_type_idx, dex_cache, referrer->GetClassLoader());
@@ -727,7 +728,7 @@
       if (!method_reference_class->IsAssignableFrom(referring_class)) {
         return nullptr;
       }
-      mirror::Class* super_class = referring_class->GetSuperClass();
+      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;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index eed08aa..fe85887 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -137,11 +137,10 @@
     REQUIRES_SHARED(Locks::mutator_lock_);
 
 // Fast path method resolution that can't throw exceptions.
+template <InvokeType type, bool access_check>
 inline ArtMethod* FindMethodFast(uint32_t method_idx,
                                  ObjPtr<mirror::Object> this_object,
-                                 ArtMethod* referrer,
-                                 bool access_check,
-                                 InvokeType type)
+                                 ArtMethod* referrer)
     REQUIRES_SHARED(Locks::mutator_lock_);
 
 inline mirror::Class* ResolveVerifyAndClinit(dex::TypeIndex type_idx,
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 2c99aeb..36885d8 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2363,7 +2363,7 @@
 // It is valid to use this, as at the usage points here (returns from C functions) we are assuming
 // to hold the mutator lock (see REQUIRES_SHARED(Locks::mutator_lock_) annotations).
 
-template<InvokeType type, bool access_check>
+template <InvokeType type, bool access_check>
 static TwoWordReturn artInvokeCommon(uint32_t method_idx,
                                      ObjPtr<mirror::Object> this_object,
                                      Thread* self,
@@ -2371,7 +2371,7 @@
   ScopedQuickEntrypointChecks sqec(self);
   DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs));
   ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp);
-  ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
+  ArtMethod* method = FindMethodFast<type, access_check>(method_idx, this_object, caller_method);
   if (UNLIKELY(method == nullptr)) {
     const DexFile* dex_file = caller_method->GetDeclaringClass()->GetDexCache()->GetDexFile();
     uint32_t shorty_len;
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 12baf38..419a4db 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -99,7 +99,7 @@
 inline uint32_t Class::GetCopiedMethodsStartOffset() {
   // Object::GetFieldShort returns an int16_t value, but
   // Class::copied_methods_offset_ is an uint16_t value; cast the
-  // latter to int16_t before returning it as an uint32_t value, so
+  // latter to uint16_t before returning it as an uint32_t value, so
   // that uint16_t values between 2^15 and 2^16-1 are correctly
   // handled.
   return static_cast<uint16_t>(
@@ -113,7 +113,7 @@
 inline uint32_t Class::GetVirtualMethodsStartOffset() {
   // Object::GetFieldShort returns an int16_t value, but
   // Class::virtual_method_offset_ is an uint16_t value; cast the
-  // latter to int16_t before returning it as an uint32_t value, so
+  // latter to uint16_t before returning it as an uint32_t value, so
   // that uint16_t values between 2^15 and 2^16-1 are correctly
   // handled.
   return static_cast<uint16_t>(
@@ -410,25 +410,24 @@
   return IsArrayAssignableFromArray(src);
 }
 
-template <bool throw_on_failure, bool use_referrers_cache>
+template <bool throw_on_failure>
 inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to,
                                            ArtField* field,
-                                           uint32_t field_idx,
-                                           ObjPtr<DexCache> dex_cache) {
-  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
+                                           ObjPtr<DexCache> dex_cache,
+                                           uint32_t field_idx) {
+  DCHECK(dex_cache != nullptr);
   if (UNLIKELY(!this->CanAccess(access_to))) {
     // The referrer class can't access the field's declaring class but may still be able
     // to access the field if the FieldId specifies an accessible subclass of the declaring
     // class rather than the declaring class itself.
-    ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
-    dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
+    dex::TypeIndex class_idx = dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
     // The referenced class has already been resolved with the field, but may not be in the dex
     // cache. Use LookupResolveType here to search the class table if it is not in the dex cache.
     // should be no thread suspension due to the class being resolved.
     ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
-        *referrer_dex_cache->GetDexFile(),
+        *dex_cache->GetDexFile(),
         class_idx,
-        referrer_dex_cache,
+        dex_cache,
         access_to->GetClassLoader());
     DCHECK(dex_access_to != nullptr);
     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
@@ -447,25 +446,25 @@
   return false;
 }
 
-template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
+template <bool throw_on_failure>
 inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
                                             ArtMethod* method,
+                                            ObjPtr<DexCache> dex_cache,
                                             uint32_t method_idx,
-                                            ObjPtr<DexCache> dex_cache) {
-  static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type");
-  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
+                                            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.
-    ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
-    dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
+    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(
-        *referrer_dex_cache->GetDexFile(),
+        *dex_cache->GetDexFile(),
         class_idx,
-        referrer_dex_cache,
+        dex_cache,
         access_to->GetClassLoader());
     DCHECK(dex_access_to != nullptr);
     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
@@ -491,30 +490,30 @@
                                           ArtField* field,
                                           ObjPtr<DexCache> dex_cache,
                                           uint32_t field_idx) {
-  return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
+  return ResolvedFieldAccessTest<false>(access_to, field, dex_cache, field_idx);
 }
 
 inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
                                             ArtField* field,
+                                            ObjPtr<DexCache> dex_cache,
                                             uint32_t field_idx) {
-  return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
+  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, false, kStatic>(access_to, method, method_idx, dex_cache);
+  return ResolvedMethodAccessTest<false>(access_to, method, dex_cache, method_idx, kStatic);
 }
 
-template <InvokeType throw_invoke_type>
 inline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to,
                                              ArtMethod* method,
-                                             uint32_t method_idx) {
-  return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to,
-                                                                 method,
-                                                                 method_idx,
-                                                                 nullptr);
+                                             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::IsSubClass(ObjPtr<Class> klass) {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 61d6e05..00498bc 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -643,7 +643,10 @@
                               ObjPtr<DexCache> dex_cache,
                               uint32_t field_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  bool CheckResolvedFieldAccess(ObjPtr<Class> access_to, ArtField* field, uint32_t field_idx)
+  bool CheckResolvedFieldAccess(ObjPtr<Class> access_to,
+                                ArtField* field,
+                                ObjPtr<DexCache> dex_cache,
+                                uint32_t field_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Can this class access a resolved method?
@@ -654,10 +657,11 @@
                                ObjPtr<DexCache> dex_cache,
                                uint32_t method_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
-  template <InvokeType throw_invoke_type>
   bool CheckResolvedMethodAccess(ObjPtr<Class> access_to,
                                  ArtMethod* resolved_method,
-                                 uint32_t method_idx)
+                                 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_);
@@ -1352,18 +1356,19 @@
                                                                     uint32_t end_offset)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  template <bool throw_on_failure, bool use_referrers_cache>
+  template <bool throw_on_failure>
   bool ResolvedFieldAccessTest(ObjPtr<Class> access_to,
                                ArtField* field,
-                               uint32_t field_idx,
-                               ObjPtr<DexCache> dex_cache)
+                               ObjPtr<DexCache> dex_cache,
+                               uint32_t field_idx)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
+  template <bool throw_on_failure>
   bool ResolvedMethodAccessTest(ObjPtr<Class> access_to,
                                 ArtMethod* resolved_method,
+                                ObjPtr<DexCache> dex_cache,
                                 uint32_t method_idx,
-                                ObjPtr<DexCache> dex_cache)
+                                InvokeType throw_invoke_type)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   bool Implements(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index a110ed7..5b1ba8d 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -106,12 +106,12 @@
 
   EXPECT_NE(klass1->NumStaticFields(), 0u);
   for (ArtField& field : klass2->GetSFields()) {
-    EXPECT_FALSE((
-        klass1->ResolvedFieldAccessTest</*throw_on_failure*/ false,
-            /*use_referrers_cache*/ false>(klass2.Get(),
-                                           &field,
-                                           field.GetDexFieldIndex(),
-                                           klass1->GetDexCache())));
+    EXPECT_FALSE(
+        klass1->ResolvedFieldAccessTest</*throw_on_failure*/ false>(
+            klass2.Get(),
+            &field,
+            klass1->GetDexCache(),
+            field.GetDexFieldIndex()));
   }
 }