ART: Change method lookup to be more consistent to JLS and the RI.

The method lookup for different invoke types was previously
widely different and didn't work well with the dex cache
method array where we have only a single slot for each
MethodId. The new behavior is to perform the same lookup for
all cases, distinguishing only between interface and
non-interface referencing class, and to further align the
behavior with the JLS and the RI. Where the JLS conflicts
with the RI, we follow the JLS semantics.

The new lookup for class methods first searches the methods
declared in the superclass chain (ignoring "copied" methods)
and only then looks in the "copied" methods. If the search
in the superclass chain finds a method that has not been
inherited (i.e. either a private method or a package-access
method where one of the classes in the chain does not belong
to the same package, see JLS 8.4.8), we still search the
"copied" methods as there may actually be a method inherited
from an interface. This follows the JLS semantics where
inherited methods are included in the search (JLS 15.12.2.1)
but conflicts with the RI where the private or
package-access method takes precedence over methods
inherited from interfaces.

Note that this search can find an accessible method that is
not inherited by the qualifying type, either for a package
access method when the referrer is in the same package but
the qualifying type is in another package, or for a private
method where the referrer is in the same class but the
qualifying type is actually a subclass. For the moment we
allow such calls and we shall consider whether to throw
an IncompatibleClassChangeError in this situation in future
to comply with JLS 15.12.4.3.

The new lookup for interface methods searches the interface
class, then all the superinterfaces and then the
java.lang.Object class, see implicitly declared methods in
interfaces, JLS 9.2. The search for the maximally-specific
non-abstract superinterface method is not yet implemented,
but the difference should be difficult to observe as the
usual subsequent call to FindVirtualMethodForInterface()
should yield the same result for any matching method.

The new test 162-method-idx-clash exposes several cases
where we previously completely messed up due to the effects
of the DexCache, or where we were out of line with the RI.
It also tests a case where the JLS and the RI disagree and
we follow the JLS.

Test: art/test/run-test --host --jvm 162-method-resolution
Test: m test-art-host-gtest
Test: testrunner.py --host
Test: testrunner.py --host --interp-ac
Test: Nexus 6P boots.
Test: testrunner.py --target
Bug: 62855082
Bug: 30627598
Change-Id: If450c8cff2751369011d649c25d28a482a2c61a3
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 3683695..08145e2 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -265,8 +265,8 @@
   mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
   CHECK(klass != nullptr) << "Class not found " << class_name;
   auto pointer_size = class_linker_->GetImagePointerSize();
-  ArtMethod* method = klass->FindDirectMethod(method_name, signature, pointer_size);
-  CHECK(method != nullptr) << "Direct method not found: "
+  ArtMethod* method = klass->FindClassMethod(method_name, signature, pointer_size);
+  CHECK(method != nullptr && method->IsDirect()) << "Direct method not found: "
       << class_name << "." << method_name << signature;
   CompileMethod(method);
 }
@@ -279,8 +279,8 @@
   mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), class_loader);
   CHECK(klass != nullptr) << "Class not found " << class_name;
   auto pointer_size = class_linker_->GetImagePointerSize();
-  ArtMethod* method = klass->FindVirtualMethod(method_name, signature, pointer_size);
-  CHECK(method != nullptr) << "Virtual method not found: "
+  ArtMethod* method = klass->FindClassMethod(method_name, signature, pointer_size);
+  CHECK(method != nullptr && !method->IsDirect()) << "Virtual method not found: "
       << class_name << "." << method_name << signature;
   CompileMethod(method);
 }
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index fba1136..9d57b96 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -291,13 +291,14 @@
   ScopedObjectAccess soa(Thread::Current());
 
   ClassLinker* class_linker = unit_.GetClassLinker();
-  ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>(
-      GetDexFile(),
-      method_idx,
-      unit_.GetDexCache(),
-      unit_.GetClassLoader(),
-      /* referrer */ nullptr,
-      kVirtual);
+  ArtMethod* resolved_method =
+      class_linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
+          GetDexFile(),
+          method_idx,
+          unit_.GetDexCache(),
+          unit_.GetClassLoader(),
+          /* referrer */ nullptr,
+          kVirtual);
 
   if (UNLIKELY(resolved_method == nullptr)) {
     // Clean up any exception left by type resolution.
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index db95bd6..b043929 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -111,7 +111,7 @@
     InvokeType invoke_type) {
   DCHECK_EQ(class_loader.Get(), mUnit->GetClassLoader().Get());
   ArtMethod* resolved_method =
-      mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>(
+      mUnit->GetClassLinker()->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
           *dex_cache->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type);
   if (UNLIKELY(resolved_method == nullptr)) {
     DCHECK(soa.Self()->IsExceptionPending());
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 83d7a3d..24b146d 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -374,14 +374,12 @@
       REQUIRES_SHARED(Locks::mutator_lock_) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   PointerSize image_size = class_linker->GetImagePointerSize();
-  mirror::Class* cls = class_linker->FindSystemClass(self, class_name);
+  ObjPtr<mirror::Class> cls = class_linker->FindSystemClass(self, class_name);
   if (cls == nullptr) {
     LOG(FATAL) << "Could not find class of intrinsic " << class_name;
   }
-  ArtMethod* method = (invoke_type == kStatic || invoke_type == kDirect)
-      ? cls->FindDeclaredDirectMethod(method_name, signature, image_size)
-      : cls->FindDeclaredVirtualMethod(method_name, signature, image_size);
-  if (method == nullptr) {
+  ArtMethod* method = cls->FindClassMethod(method_name, signature, image_size);
+  if (method == nullptr || method->GetDeclaringClass() != cls) {
     LOG(FATAL) << "Could not find method of intrinsic "
                << class_name << " " << method_name << " " << signature;
   }
@@ -544,7 +542,7 @@
 
       // TODO: Lookup annotation from DexFile directly without resolving method.
       ArtMethod* method =
-          Runtime::Current()->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+          Runtime::Current()->GetClassLinker()->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
               dex_file,
               method_idx,
               dex_cache,
@@ -1756,7 +1754,7 @@
       }
       if (resolve_fields_and_methods) {
         while (it.HasNextDirectMethod()) {
-          ArtMethod* method = class_linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+          ArtMethod* method = class_linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
               dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
               it.GetMethodInvokeType(class_def));
           if (method == nullptr) {
@@ -1765,7 +1763,7 @@
           it.Next();
         }
         while (it.HasNextVirtualMethod()) {
-          ArtMethod* method = class_linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+          ArtMethod* method = class_linker->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
               dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
               it.GetMethodInvokeType(class_def));
           if (method == nullptr) {
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index b4777df..0b3ca69 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -102,12 +102,14 @@
       CHECK_ALIGNED(stack_maps_offset, 2);
     }
 
-    method_f_ = my_klass_->FindVirtualMethod("f", "()I", kRuntimePointerSize);
+    method_f_ = my_klass_->FindClassMethod("f", "()I", kRuntimePointerSize);
     ASSERT_TRUE(method_f_ != nullptr);
+    ASSERT_FALSE(method_f_->IsDirect());
     method_f_->SetEntryPointFromQuickCompiledCode(code_ptr);
 
-    method_g_ = my_klass_->FindVirtualMethod("g", "(I)V", kRuntimePointerSize);
+    method_g_ = my_klass_->FindClassMethod("g", "(I)V", kRuntimePointerSize);
     ASSERT_TRUE(method_g_ != nullptr);
+    ASSERT_FALSE(method_g_->IsDirect());
     method_g_->SetEntryPointFromQuickCompiledCode(code_ptr);
   }
 
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 9d7aff7..252fdd6 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -113,9 +113,9 @@
   mirror::Class* iface_klass = class_linker_->LookupClass(
       self, "LIface;", ObjPtr<mirror::ClassLoader>());
   ASSERT_NE(nullptr, iface_klass);
-  ArtMethod* origin = iface_klass->FindDeclaredVirtualMethod(
-      "defaultMethod", "()V", pointer_size);
+  ArtMethod* origin = iface_klass->FindInterfaceMethod("defaultMethod", "()V", pointer_size);
   ASSERT_NE(nullptr, origin);
+  ASSERT_TRUE(origin->GetDeclaringClass() == iface_klass);
   const void* code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
   // The origin method should have a pointer to quick code
   ASSERT_NE(nullptr, code);
@@ -134,9 +134,11 @@
   mirror::Class* iterable_klass = class_linker_->LookupClass(
       self, "Ljava/lang/Iterable;", ObjPtr<mirror::ClassLoader>());
   ASSERT_NE(nullptr, iterable_klass);
-  origin = iterable_klass->FindDeclaredVirtualMethod(
+  origin = iterable_klass->FindClassMethod(
       "forEach", "(Ljava/util/function/Consumer;)V", pointer_size);
   ASSERT_NE(nullptr, origin);
+  ASSERT_FALSE(origin->IsDirect());
+  ASSERT_TRUE(origin->GetDeclaringClass() == iterable_klass);
   code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
   // the origin method should have a pointer to quick code
   ASSERT_NE(nullptr, code);
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 6ce7d75..40e5645 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -247,9 +247,9 @@
     // Compile the native method before starting the runtime
     mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader);
     const auto pointer_size = class_linker_->GetImagePointerSize();
-    ArtMethod* method = direct ? c->FindDirectMethod(method_name, method_sig, pointer_size) :
-        c->FindVirtualMethod(method_name, method_sig, pointer_size);
+    ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
     ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
+    ASSERT_EQ(direct, method->IsDirect()) << method_name << " " << method_sig;
     if (check_generic_jni_) {
       method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
     } else {
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 6120ed0..f8bb417 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -1143,11 +1143,13 @@
         // in the copied method should be the same as in the origin
         // method.
         mirror::Class* declaring_class = method.GetDeclaringClass();
-        ArtMethod* origin = declaring_class->FindDeclaredVirtualMethod(
+        ArtMethod* origin = declaring_class->FindClassMethod(
             declaring_class->GetDexCache(),
             method.GetDexMethodIndex(),
             pointer_size_);
         CHECK(origin != nullptr);
+        CHECK(!origin->IsDirect());
+        CHECK(origin->GetDeclaringClass() == declaring_class);
         if (IsInOatFile(&declaring_class->GetDexFile())) {
           const void* code_ptr =
               origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size_);
@@ -1189,7 +1191,7 @@
     if (writer_->HasBootImage()) {
       const InvokeType invoke_type = it.GetMethodInvokeType(
           dex_file_->GetClassDef(class_def_index_));
-      method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+      method = class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
           *dex_file_,
           it.GetMemberIndex(),
           dex_cache,
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 839f328..8054140 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -664,10 +664,7 @@
     // TODO: remove redundant constructor fences (b/36656456).
     if (RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_)) {
       // Compiling instance constructor.
-      if (kIsDebugBuild) {
-        std::string method_name = graph_->GetMethodName();
-        CHECK_EQ(std::string("<init>"), method_name);
-      }
+      DCHECK_STREQ("<init>", graph_->GetMethodName());
 
       HInstruction* fence_target = current_this_parameter_;
       DCHECK(fence_target != nullptr);
@@ -710,29 +707,18 @@
 
 ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) {
   ScopedObjectAccess soa(Thread::Current());
-  StackHandleScope<2> hs(soa.Self());
 
   ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker();
   Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader();
-  Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass()));
-  // We fetch the referenced class eagerly (that is, the class pointed by in the MethodId
-  // at method_idx), as `CanAccessResolvedMethod` expects it be be in the dex cache.
-  Handle<mirror::Class> methods_class(hs.NewHandle(class_linker->ResolveReferencedClassOfMethod(
-      method_idx, dex_compilation_unit_->GetDexCache(), class_loader)));
 
-  if (UNLIKELY(methods_class == nullptr)) {
-    // Clean up any exception left by type resolution.
-    soa.Self()->ClearException();
-    return nullptr;
-  }
-
-  ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>(
-      *dex_compilation_unit_->GetDexFile(),
-      method_idx,
-      dex_compilation_unit_->GetDexCache(),
-      class_loader,
-      /* referrer */ nullptr,
-      invoke_type);
+  ArtMethod* resolved_method =
+      class_linker->ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
+          *dex_compilation_unit_->GetDexFile(),
+          method_idx,
+          dex_compilation_unit_->GetDexCache(),
+          class_loader,
+          graph_->GetArtMethod(),
+          invoke_type);
 
   if (UNLIKELY(resolved_method == nullptr)) {
     // Clean up any exception left by type resolution.
@@ -740,17 +726,14 @@
     return nullptr;
   }
 
-  // Check access. The class linker has a fast path for looking into the dex cache
-  // and does not check the access if it hits it.
-  if (compiling_class == nullptr) {
+  // The referrer may be unresolved for AOT if we're compiling a class that cannot be
+  // resolved because, for example, we don't find a superclass in the classpath.
+  if (graph_->GetArtMethod() == nullptr) {
+    // The class linker cannot check access without a referrer, so we have to do it.
+    // Fall back to HInvokeUnresolved if the method isn't public.
     if (!resolved_method->IsPublic()) {
       return nullptr;
     }
-  } else if (!compiling_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
-                                                       resolved_method,
-                                                       dex_compilation_unit_->GetDexCache().Get(),
-                                                       method_idx)) {
-    return nullptr;
   }
 
   // We have to special case the invoke-super case, as ClassLinker::ResolveMethod does not.
@@ -758,19 +741,26 @@
   // make this an invoke-unresolved to handle cross-dex invokes or abstract super methods, both of
   // which require runtime handling.
   if (invoke_type == kSuper) {
+    ObjPtr<mirror::Class> compiling_class = GetCompilingClass();
     if (compiling_class == nullptr) {
       // We could not determine the method's class we need to wait until runtime.
       DCHECK(Runtime::Current()->IsAotCompiler());
       return nullptr;
     }
-    if (!methods_class->IsAssignableFrom(compiling_class.Get())) {
+    ObjPtr<mirror::Class> referenced_class = class_linker->LookupResolvedType(
+        *dex_compilation_unit_->GetDexFile(),
+        dex_compilation_unit_->GetDexFile()->GetMethodId(method_idx).class_idx_,
+        dex_compilation_unit_->GetDexCache().Get(),
+        class_loader.Get());
+    DCHECK(referenced_class != nullptr);  // We have already resolved a method from this class.
+    if (!referenced_class->IsAssignableFrom(compiling_class)) {
       // We cannot statically determine the target method. The runtime will throw a
       // NoSuchMethodError on this one.
       return nullptr;
     }
     ArtMethod* actual_method;
-    if (methods_class->IsInterface()) {
-      actual_method = methods_class->FindVirtualMethodForInterfaceSuper(
+    if (referenced_class->IsInterface()) {
+      actual_method = referenced_class->FindVirtualMethodForInterfaceSuper(
           resolved_method, class_linker->GetImagePointerSize());
     } else {
       uint16_t vtable_index = resolved_method->GetMethodIndex();
@@ -797,12 +787,6 @@
     resolved_method = actual_method;
   }
 
-  // Check for incompatible class changes. The class linker has a fast path for
-  // looking into the dex cache and does not check incompatible class changes if it hits it.
-  if (resolved_method->CheckIncompatibleClassChange(invoke_type)) {
-    return nullptr;
-  }
-
   return resolved_method;
 }
 
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index d147166..f2a8cc0 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1867,33 +1867,35 @@
       ArtMethod* method = nullptr;
       switch (source_component_type) {
         case Primitive::kPrimBoolean:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([ZI[ZII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([ZI[ZII)V", image_size);
           break;
         case Primitive::kPrimByte:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([BI[BII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([BI[BII)V", image_size);
           break;
         case Primitive::kPrimChar:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([CI[CII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([CI[CII)V", image_size);
           break;
         case Primitive::kPrimShort:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([SI[SII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([SI[SII)V", image_size);
           break;
         case Primitive::kPrimInt:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([II[III)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([II[III)V", image_size);
           break;
         case Primitive::kPrimFloat:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([FI[FII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([FI[FII)V", image_size);
           break;
         case Primitive::kPrimLong:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([JI[JII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([JI[JII)V", image_size);
           break;
         case Primitive::kPrimDouble:
-          method = system->FindDeclaredDirectMethod("arraycopy", "([DI[DII)V", image_size);
+          method = system->FindClassMethod("arraycopy", "([DI[DII)V", image_size);
           break;
         default:
           LOG(FATAL) << "Unreachable";
       }
       DCHECK(method != nullptr);
+      DCHECK(method->IsStatic());
+      DCHECK(method->GetDeclaringClass() == system);
       invoke->SetResolvedMethod(method);
       // Sharpen the new invoke. Note that we do not update the dex method index of
       // the invoke, as we would need to look it up in the current dex file, and it
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 98332d3..ecbf52b 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -526,7 +526,7 @@
       // but then we would need to pass it to RTPVisitor just for this debug check. Since
       // the method is from the String class, the null loader is good enough.
       Handle<mirror::ClassLoader> loader;
-      ArtMethod* method = cl->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+      ArtMethod* method = cl->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
           dex_file, invoke->GetDexMethodIndex(), dex_cache, loader, nullptr, kDirect);
       DCHECK(method != nullptr);
       mirror::Class* declaring_class = method->GetDeclaringClass();
diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc
index 686da21..72e2a6c 100644
--- a/compiler/verifier_deps_test.cc
+++ b/compiler/verifier_deps_test.cc
@@ -155,13 +155,14 @@
 
     ArtMethod* method = nullptr;
     while (it.HasNextDirectMethod()) {
-      ArtMethod* resolved_method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
-          *primary_dex_file_,
-          it.GetMemberIndex(),
-          dex_cache_handle,
-          class_loader_handle,
-          nullptr,
-          it.GetMethodInvokeType(*class_def));
+      ArtMethod* resolved_method =
+          class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
+              *primary_dex_file_,
+              it.GetMemberIndex(),
+              dex_cache_handle,
+              class_loader_handle,
+              nullptr,
+              it.GetMethodInvokeType(*class_def));
       CHECK(resolved_method != nullptr);
       if (method_name == resolved_method->GetName()) {
         method = resolved_method;
@@ -369,18 +370,14 @@
 
   // Iterates over all method resolution records, finds an entry which matches
   // the given field kind+class+name+signature and tests its properties.
-  bool HasMethod(const std::string& expected_kind,
-                 const std::string& expected_klass,
+  bool HasMethod(const std::string& expected_klass,
                  const std::string& expected_name,
                  const std::string& expected_signature,
                  bool expected_resolved,
                  const std::string& expected_access_flags = "",
                  const std::string& expected_decl_klass = "") {
     for (auto& dex_dep : verifier_deps_->dex_deps_) {
-      auto& storage = (expected_kind == "direct") ? dex_dep.second->direct_methods_
-                          : (expected_kind == "virtual") ? dex_dep.second->virtual_methods_
-                              : dex_dep.second->interface_methods_;
-      for (auto& entry : storage) {
+      for (const VerifierDeps::MethodResolution& entry : dex_dep.second->methods_) {
         if (expected_resolved != entry.IsResolved()) {
           continue;
         }
@@ -441,9 +438,7 @@
       has_assignability |= !entry.second->unassignable_types_.empty();
       has_classes |= !entry.second->classes_.empty();
       has_fields |= !entry.second->fields_.empty();
-      has_methods |= !entry.second->direct_methods_.empty();
-      has_methods |= !entry.second->virtual_methods_.empty();
-      has_methods |= !entry.second->interface_methods_.empty();
+      has_methods |= !entry.second->methods_.empty();
       has_unverified_classes |= !entry.second->unverified_classes_.empty();
     }
 
@@ -455,18 +450,6 @@
            has_unverified_classes;
   }
 
-  static std::set<VerifierDeps::MethodResolution>* GetMethods(
-      VerifierDeps::DexFileDeps* deps, MethodResolutionKind resolution_kind) {
-    if (resolution_kind == kDirectMethodResolution) {
-      return &deps->direct_methods_;
-    } else if (resolution_kind == kVirtualMethodResolution) {
-      return &deps->virtual_methods_;
-    } else {
-      DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
-      return &deps->interface_methods_;
-    }
-  }
-
   std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
   std::vector<const DexFile*> dex_files_;
   const DexFile* primary_dex_file_;
@@ -604,11 +587,10 @@
   ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
   ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
   ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
-  ASSERT_TRUE(HasMethod("virtual",
-                        "Ljava/text/SimpleDateFormat;",
+  ASSERT_TRUE(HasMethod("Ljava/text/SimpleDateFormat;",
                         "setTimeZone",
                         "(Ljava/util/TimeZone;)V",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/text/DateFormat;"));
   ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
@@ -840,11 +822,10 @@
 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
   ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
   ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "Ljava/net/Socket;",
+  ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
                         "setSocketImplFactory",
                         "(Ljava/net/SocketImplFactory;)V",
-                        true,
+                        /* expect_resolved */ true,
                         "public static",
                         "Ljava/net/Socket;"));
 }
@@ -852,22 +833,20 @@
 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
   ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
   ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "Ljavax/net/ssl/SSLSocket;",
+  ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
                         "setSocketImplFactory",
                         "(Ljava/net/SocketImplFactory;)V",
-                        true,
+                        /* expect_resolved */ true,
                         "public static",
                         "Ljava/net/Socket;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
   ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "LMySSLSocket;",
+  ASSERT_TRUE(HasMethod("LMySSLSocket;",
                         "setSocketImplFactory",
                         "(Ljava/net/SocketImplFactory;)V",
-                        true,
+                        /* expect_resolved */ true,
                         "public static",
                         "Ljava/net/Socket;"));
 }
@@ -875,11 +854,10 @@
 TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
   ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
   ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public interface"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "Ljava/util/Map$Entry;",
+  ASSERT_TRUE(HasMethod("Ljava/util/Map$Entry;",
                         "comparingByKey",
                         "()Ljava/util/Comparator;",
-                        true,
+                        /* expect_resolved */ true,
                         "public static",
                         "Ljava/util/Map$Entry;"));
 }
@@ -887,68 +865,85 @@
 TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
   ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
   ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "Ljava/util/AbstractMap$SimpleEntry;",
+  ASSERT_TRUE(HasMethod("Ljava/util/AbstractMap$SimpleEntry;",
                         "comparingByKey",
                         "()Ljava/util/Comparator;",
-                        false));
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
   ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
   ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
   ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
-  ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("LMySSLSocket;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
   ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
   ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
-  ASSERT_TRUE(HasMethod(
-      "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
+  ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
+                        "<init>",
+                        "()V",
+                        /* expect_resolved */ true,
+                        "public",
+                        "Ljava/net/Socket;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
   ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
   ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct",
-                        "Ljavax/net/ssl/SSLSocket;",
+  ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
                         "checkOldImpl",
                         "()V",
-                        true,
+                        /* expect_resolved */ true,
                         "private",
                         "Ljava/net/Socket;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
   ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
-  ASSERT_TRUE(HasMethod(
-      "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
+  ASSERT_TRUE(HasMethod("LMySSLSocket;",
+                        "checkOldImpl",
+                        "()V",
+                        /* expect_resolved */ true,
+                        "private",
+                        "Ljava/net/Socket;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
   ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
   ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
-  ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
   ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
-  ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("LMySSLSocket;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
   ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
-  ASSERT_TRUE(HasMethod("virtual",
-                        "Ljava/lang/Throwable;",
+  ASSERT_TRUE(HasMethod("Ljava/lang/Throwable;",
                         "getMessage",
                         "()Ljava/lang/String;",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/lang/Throwable;"));
   // Type dependency on `this` argument.
@@ -958,11 +953,10 @@
 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
   ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
-  ASSERT_TRUE(HasMethod("virtual",
-                        "Ljava/io/InterruptedIOException;",
+  ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
                         "getMessage",
                         "()Ljava/lang/String;",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/lang/Throwable;"));
   // Type dependency on `this` argument.
@@ -971,22 +965,20 @@
 
 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
-  ASSERT_TRUE(HasMethod("virtual",
-                        "LMySocketTimeoutException;",
+  ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
                         "getMessage",
                         "()Ljava/lang/String;",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/lang/Throwable;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
-  ASSERT_TRUE(HasMethod("virtual",
-                        "LMyThreadSet;",
+  ASSERT_TRUE(HasMethod("LMyThreadSet;",
                         "size",
                         "()I",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/util/Set;"));
 }
@@ -994,61 +986,59 @@
 TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
   ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
   ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
-  ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
   ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
-  ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
-}
-
-TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
-  ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
-  ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
-  ASSERT_TRUE(HasMethod("direct",
-                        "LMyThread;",
-                        "activeCount",
-                        "()I",
-                        true,
-                        "public static",
-                        "Ljava/lang/Thread;"));
+  ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
   ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
   ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
-  ASSERT_TRUE(HasMethod("interface",
-                        "Ljava/lang/Runnable;",
+  ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
                         "run",
                         "()V",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/lang/Runnable;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
   ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
-  ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
+  // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
+  ASSERT_TRUE(HasMethod("LMyThread;",
+                        "join",
+                        "()V",
+                        /* expect_resolved */ true,
+                        "public",
+                        "Ljava/lang/Thread;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
   ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
-  ASSERT_TRUE(HasMethod("interface",
-                        "LMyThreadSet;",
+  // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
+  ASSERT_TRUE(HasMethod("LMyThreadSet;",
                         "run",
                         "()V",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
-                        "Ljava/lang/Runnable;"));
+                        "Ljava/lang/Thread;"));
 }
 
 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
   ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
-  ASSERT_TRUE(HasMethod("interface",
-                        "LMyThreadSet;",
+  ASSERT_TRUE(HasMethod("LMyThreadSet;",
                         "isEmpty",
                         "()Z",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/util/Set;"));
 }
@@ -1056,23 +1046,25 @@
 TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
   ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
   ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
-  ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
+                        "x",
+                        "()V",
+                        /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
   ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
-  ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
+  ASSERT_TRUE(HasMethod("LMyThreadSet;", "x", "()V", /* expect_resolved */ false));
 }
 
 TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
   ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
   ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
   ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true));
-  ASSERT_TRUE(HasMethod("interface",
-                        "Ljava/lang/Runnable;",
+  ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
                         "run",
                         "()V",
-                        true,
+                        /* expect_resolved */ true,
                         "public",
                         "Ljava/lang/Runnable;"));
 }
@@ -1081,8 +1073,10 @@
   ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
   ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public"));
   ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false));
-  ASSERT_TRUE(HasMethod(
-      "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
+  ASSERT_TRUE(HasMethod("Ljava/lang/Integer;",
+                        "intValue", "()I",
+                        /* expect_resolved */ true,
+                        "public", "Ljava/lang/Integer;"));
 }
 
 TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
@@ -1150,18 +1144,6 @@
   ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
 }
 
-// Returns the next resolution kind in the enum.
-static MethodResolutionKind GetNextResolutionKind(MethodResolutionKind resolution_kind) {
-  if (resolution_kind == kDirectMethodResolution) {
-    return kVirtualMethodResolution;
-  } else if (resolution_kind == kVirtualMethodResolution) {
-    return kInterfaceMethodResolution;
-  } else {
-    DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
-    return kDirectMethodResolution;
-  }
-}
-
 TEST_F(VerifierDepsTest, VerifyDeps) {
   VerifyDexFile();
 
@@ -1338,131 +1320,82 @@
   }
 
   // Mess up with methods.
-  for (MethodResolutionKind resolution_kind :
-            { kDirectMethodResolution, kVirtualMethodResolution, kInterfaceMethodResolution }) {
-    {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        if (entry.IsResolved()) {
-          methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
-                                                         VerifierDeps::kUnresolvedMarker,
-                                                         entry.GetDeclaringClassIndex()));
-          found = true;
-          break;
-        }
+  {
+    VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
+    VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
+    bool found = false;
+    std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
+    for (const auto& entry : *methods) {
+      if (entry.IsResolved()) {
+        methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
+                                                       VerifierDeps::kUnresolvedMarker,
+                                                       entry.GetDeclaringClassIndex()));
+        found = true;
+        break;
       }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
     }
+    ASSERT_TRUE(found);
+    new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
+    ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
+  }
 
-    {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        if (!entry.IsResolved()) {
-          constexpr dex::StringIndex kStringIndexZero(0);  // We know there is a class there.
-          methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
-                                                         VerifierDeps::kUnresolvedMarker - 1,
-                                                         kStringIndexZero));
-          found = true;
-          break;
-        }
+  {
+    VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
+    VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
+    bool found = false;
+    std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
+    for (const auto& entry : *methods) {
+      if (!entry.IsResolved()) {
+        constexpr dex::StringIndex kStringIndexZero(0);  // We know there is a class there.
+        methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
+                                                       VerifierDeps::kUnresolvedMarker - 1,
+                                                       kStringIndexZero));
+        found = true;
+        break;
       }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
     }
+    ASSERT_TRUE(found);
+    new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
+    ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
+  }
 
-    {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        if (entry.IsResolved()) {
-          methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
-                                                         entry.GetAccessFlags() - 1,
-                                                         entry.GetDeclaringClassIndex()));
-          found = true;
-          break;
-        }
+  {
+    VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
+    VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
+    bool found = false;
+    std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
+    for (const auto& entry : *methods) {
+      if (entry.IsResolved()) {
+        methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
+                                                       entry.GetAccessFlags() - 1,
+                                                       entry.GetDeclaringClassIndex()));
+        found = true;
+        break;
       }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
     }
+    ASSERT_TRUE(found);
+    new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
+    ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
+  }
 
-    {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        constexpr dex::StringIndex kNewTypeIndex(0);
-        if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
-          methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
-                                                         entry.GetAccessFlags(),
-                                                         kNewTypeIndex));
-          found = true;
-          break;
-        }
+  {
+    VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
+    VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
+    bool found = false;
+    std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
+    for (const auto& entry : *methods) {
+      constexpr dex::StringIndex kNewTypeIndex(0);
+      if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
+        methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
+                                                       entry.GetAccessFlags(),
+                                                       kNewTypeIndex));
+        found = true;
+        break;
       }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
     }
-
-    // The two tests below make sure that fiddling with the method kind
-    // (static, virtual, interface) is detected by `ValidateDependencies`.
-
-    // An interface method lookup can succeed with a virtual method lookup on the same class.
-    // That's OK, as we only want to make sure there is a method being defined with the right
-    // flags. Therefore, polluting the interface methods with virtual methods does not have
-    // to fail verification.
-    if (resolution_kind != kVirtualMethodResolution) {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        if (entry.IsResolved()) {
-          GetMethods(deps, GetNextResolutionKind(resolution_kind))->insert(
-              VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
-                                             entry.GetAccessFlags(),
-                                             entry.GetDeclaringClassIndex()));
-          found = true;
-        }
-      }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
-    }
-
-    // See comment above that applies the same way.
-    if (resolution_kind != kInterfaceMethodResolution) {
-      VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
-      VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
-      bool found = false;
-      std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
-      for (const auto& entry : *methods) {
-        if (entry.IsResolved()) {
-          GetMethods(deps, GetNextResolutionKind(GetNextResolutionKind(resolution_kind)))->insert(
-              VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
-                                             entry.GetAccessFlags(),
-                                             entry.GetDeclaringClassIndex()));
-          found = true;
-        }
-      }
-      ASSERT_TRUE(found);
-      new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
-      ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
-    }
+    ASSERT_TRUE(found);
+    new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
+    ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
   }
 }