Fix vdex fast-verify performance regression

Recent CL I0d06b82e31088c58d4493723a5435309740f1d0c generalized the
fast-verify class redefinition check by checking that all vdex-verified
classes resolve to dex files covered by the vdex and are not duplicates
of classes in parent class loaders. This introduced a performance and
allocated memory regression for dex2oat invoked with
compiler-filter=verify(-profile).

This patch removes the regression by acquiring a list of classpath dex
files from the compiler driver and boot classpath dex files from the
class linker, avoiding class resolution altogether.

A small performance overhead remains as previously only boot classpath
was being searched.

Test: run `dex2oat filter=interpret-only; dex2oat filter=verify`
      compare time and allocated memory numbers before CL and after
Change-Id: Ifd690cdafdc99d3eafb9847d67775fc11a5b5023
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 54e94d0..33201cf 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1786,7 +1786,13 @@
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
   std::string error_msg;
 
-  if (!verifier_deps->ValidateDependencies(class_loader, soa.Self(), &error_msg)) {
+  if (!verifier_deps->ValidateDependencies(
+      soa.Self(),
+      class_loader,
+      // This returns classpath dex files in no particular order but VerifierDeps
+      // does not care about the order.
+      classpath_classes_.GetDexFiles(),
+      &error_msg)) {
     LOG(WARNING) << "Fast verification failed: " << error_msg;
     return false;
   }
diff --git a/compiler/utils/atomic_dex_ref_map-inl.h b/compiler/utils/atomic_dex_ref_map-inl.h
index 9915498..377b7fe 100644
--- a/compiler/utils/atomic_dex_ref_map-inl.h
+++ b/compiler/utils/atomic_dex_ref_map-inl.h
@@ -134,6 +134,17 @@
   }
 }
 
+template <typename DexFileReferenceType, typename Value>
+inline std::vector<const DexFile*> AtomicDexRefMap<DexFileReferenceType, Value>::GetDexFiles()
+    const {
+  std::vector<const DexFile*> result;
+  result.reserve(arrays_.size());
+  for (auto& it : arrays_) {
+    result.push_back(it.first);
+  }
+  return result;
+}
+
 }  // namespace art
 
 #endif  // ART_COMPILER_UTILS_ATOMIC_DEX_REF_MAP_INL_H_
diff --git a/compiler/utils/atomic_dex_ref_map.h b/compiler/utils/atomic_dex_ref_map.h
index fc24379..a8c285f 100644
--- a/compiler/utils/atomic_dex_ref_map.h
+++ b/compiler/utils/atomic_dex_ref_map.h
@@ -54,6 +54,9 @@
   void AddDexFile(const DexFile* dex_file);
   void AddDexFiles(const std::vector<const DexFile*>& dex_files);
 
+  // Return a vector of all dex files which were added to the map.
+  std::vector<const DexFile*> GetDexFiles() const;
+
   bool HaveDexFile(const DexFile* dex_file) const {
     return arrays_.find(dex_file) != arrays_.end();
   }
diff --git a/compiler/utils/atomic_dex_ref_map_test.cc b/compiler/utils/atomic_dex_ref_map_test.cc
index 4e1ef12..864531e 100644
--- a/compiler/utils/atomic_dex_ref_map_test.cc
+++ b/compiler/utils/atomic_dex_ref_map_test.cc
@@ -41,6 +41,9 @@
   EXPECT_TRUE(map.Insert(MethodReference(dex.get(), 1), 0, 1) == Map::kInsertResultInvalidDexFile);
   map.AddDexFile(dex.get());
   EXPECT_TRUE(map.HaveDexFile(dex.get()));
+  std::vector<const DexFile*> registered_dex_files = map.GetDexFiles();
+  EXPECT_EQ(1u, registered_dex_files.size());
+  EXPECT_TRUE(registered_dex_files[0] == dex.get());
   EXPECT_GT(dex->NumMethodIds(), 10u);
   // After we have added the get should succeed but return the default value.
   EXPECT_TRUE(map.Get(MethodReference(dex.get(), 1), &value));