Dump Dex file checksums for profman --dump-only

Make it easier to diagnose mismatched dex checksums. Add checksum
verification in ProfileCompilationInfo::DumpInfo. Some refactoring
to remove unnecessary code.

Bug: 116509324
Test: test-art-host-gtest

Change-Id: I11fb8d1aa987c0f0a975ef6dcb811bf41d58fad6
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 95d08b3..df84b25 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2647,7 +2647,7 @@
     LOG(INFO) << "[ProfileGuidedCompilation] " <<
         ((profile_compilation_info_ == nullptr)
             ? "null"
-            : profile_compilation_info_->DumpInfo(&dex_files));
+            : profile_compilation_info_->DumpInfo(dex_files));
   }
 
   dex_to_dex_compiler_.ClearState();
diff --git a/libprofile/profile/profile_compilation_info.cc b/libprofile/profile/profile_compilation_info.cc
index f5e08da..2ebde5e 100644
--- a/libprofile/profile/profile_compilation_info.cc
+++ b/libprofile/profile/profile_compilation_info.cc
@@ -1636,25 +1636,7 @@
   return total;
 }
 
-// Produce a non-owning vector from a vector.
-template<typename T>
-const std::vector<T*>* MakeNonOwningVector(const std::vector<std::unique_ptr<T>>* owning_vector) {
-  auto non_owning_vector = new std::vector<T*>();
-  for (auto& element : *owning_vector) {
-    non_owning_vector->push_back(element.get());
-  }
-  return non_owning_vector;
-}
-
-std::string ProfileCompilationInfo::DumpInfo(
-    const std::vector<std::unique_ptr<const DexFile>>* dex_files,
-    bool print_full_dex_location) const {
-  std::unique_ptr<const std::vector<const DexFile*>> non_owning_dex_files(
-      MakeNonOwningVector(dex_files));
-  return DumpInfo(non_owning_dex_files.get(), print_full_dex_location);
-}
-
-std::string ProfileCompilationInfo::DumpInfo(const std::vector<const DexFile*>* dex_files,
+std::string ProfileCompilationInfo::DumpInfo(const std::vector<const DexFile*>& dex_files,
                                              bool print_full_dex_location) const {
   std::ostringstream os;
   if (info_.empty()) {
@@ -1677,11 +1659,10 @@
     os << " [index=" << static_cast<uint32_t>(dex_data->profile_index) << "]";
     os << " [checksum=" << std::hex << dex_data->checksum << "]" << std::dec;
     const DexFile* dex_file = nullptr;
-    if (dex_files != nullptr) {
-      for (size_t i = 0; i < dex_files->size(); i++) {
-        if (dex_data->profile_key == (*dex_files)[i]->GetLocation()) {
-          dex_file = (*dex_files)[i];
-        }
+    for (const DexFile* current : dex_files) {
+      if (dex_data->profile_key == current->GetLocation() &&
+          dex_data->checksum == current->GetLocationChecksum()) {
+        dex_file = current;
       }
     }
     os << "\n\thot methods: ";
diff --git a/libprofile/profile/profile_compilation_info.h b/libprofile/profile/profile_compilation_info.h
index 0dbf490..92fa098 100644
--- a/libprofile/profile/profile_compilation_info.h
+++ b/libprofile/profile/profile_compilation_info.h
@@ -377,12 +377,10 @@
                                                       uint16_t dex_method_index) const;
 
   // Dump all the loaded profile info into a string and returns it.
-  // If dex_files is not null then the method indices will be resolved to their
+  // If dex_files is not empty then the method indices will be resolved to their
   // names.
   // This is intended for testing and debugging.
-  std::string DumpInfo(const std::vector<std::unique_ptr<const DexFile>>* dex_files,
-                       bool print_full_dex_location = true) const;
-  std::string DumpInfo(const std::vector<const DexFile*>* dex_files,
+  std::string DumpInfo(const std::vector<const DexFile*>& dex_files,
                        bool print_full_dex_location = true) const;
 
   // Return the classes and methods for a given dex file through out args. The out args are the set
diff --git a/profman/profman.cc b/profman/profman.cc
index cecd3c2..2b5bf48 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -35,6 +35,7 @@
 #include "base/logging.h"  // For InitLogging.
 #include "base/mem_map.h"
 #include "base/scoped_flock.h"
+#include "base/stl_util.h"
 #include "base/stringpiece.h"
 #include "base/time_utils.h"
 #include "base/unix_file/fd_file.h"
@@ -500,7 +501,7 @@
       LOG(ERROR) << "Cannot load profile info from filename=" << filename << " fd=" << fd;
       return -1;
     }
-    *dump += banner + "\n" + info->DumpInfo(dex_files) + "\n";
+    *dump += banner + "\n" + info->DumpInfo(MakeNonOwningPointerVector(*dex_files)) + "\n";
     return 0;
   }
 
@@ -513,10 +514,23 @@
     static const char* kEmptyString = "";
     static const char* kOrdinaryProfile = "=== profile ===";
     static const char* kReferenceProfile = "=== reference profile ===";
+    static const char* kDexFiles = "=== Dex files  ===";
 
     std::vector<std::unique_ptr<const DexFile>> dex_files;
     OpenApkFilesFromLocations(&dex_files);
+
     std::string dump;
+
+    // Dump checkfiles and corresponding checksums.
+    dump += kDexFiles;
+    dump += "\n";
+    for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
+      std::ostringstream oss;
+      oss << dex_file->GetLocation()
+          << " [checksum=" << std::hex << dex_file->GetLocationChecksum() << "]\n";
+      dump += oss.str();
+    }
+
     // Dump individual profile files.
     if (!profile_files_fd_.empty()) {
       for (int profile_file_fd : profile_files_fd_) {
@@ -530,12 +544,10 @@
         }
       }
     }
-    if (!profile_files_.empty()) {
-      for (const std::string& profile_file : profile_files_) {
-        int ret = DumpOneProfile(kOrdinaryProfile, profile_file, kInvalidFd, &dex_files, &dump);
-        if (ret != 0) {
-          return ret;
-        }
+    for (const std::string& profile_file : profile_files_) {
+      int ret = DumpOneProfile(kOrdinaryProfile, profile_file, kInvalidFd, &dex_files, &dump);
+      if (ret != 0) {
+        return ret;
       }
     }
     // Dump reference profile file.