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.