Refactor the management of profile keys

Make the profile key generation dependent on the actual profile object
(non-static). This will allow us to add additional information into the
key, depending on the profile version. For example, for the boot image, we
may add the architecture so that we can capture the differences between 32
and 64 bits.

Bug: 139884006
Test: m test-art-host
Change-Id: Id1ad60ac50adcf8bfe011b8d843c4cc4e9d5fc0f
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 8c03307..e866330 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -641,7 +641,7 @@
     CHECK_GE(profile_test_fd, 0);
 
     ProfileCompilationInfo info;
-    std::string profile_key = ProfileCompilationInfo::GetProfileDexFileKey(dex_location);
+    std::string profile_key = info.GetProfileDexFileKey(dex_location);
     for (size_t i = 0; i < num_classes; ++i) {
       info.AddClassIndex(profile_key, checksum, dex::TypeIndex(1 + i), kMaxMethodIds);
     }
diff --git a/libprofile/profile/profile_compilation_info.cc b/libprofile/profile/profile_compilation_info.cc
index 097c30c..2a4d7ec 100644
--- a/libprofile/profile/profile_compilation_info.cc
+++ b/libprofile/profile/profile_compilation_info.cc
@@ -147,11 +147,21 @@
   classes.insert(ref);
 }
 
-// Transform the actual dex location into relative paths.
+// Transform the actual dex location into a key used to index the dex file in the profile.
+// See ProfileCompilationInfo#GetProfileDexFileBaseKey as well.
+// For regular profiles (non-boot) the profile key is the same as its base key.
+std::string ProfileCompilationInfo::GetProfileDexFileKey(const std::string& dex_location) const {
+  // TODO(calin): append the RuntimeInstructionSet to the key so we can capture arch-dependent data.
+  // This requires a bit of work as the ProfileSaver and various tests rely on this being a
+  // static public method.
+  return GetProfileDexFileBaseKey(dex_location);
+}
+
+// Transform the actual dex location into a base profile key (represented as relative paths).
 // Note: this is OK because we don't store profiles of different apps into the same file.
 // Apps with split apks don't cause trouble because each split has a different name and will not
 // collide with other entries.
-std::string ProfileCompilationInfo::GetProfileDexFileKey(const std::string& dex_location) {
+std::string ProfileCompilationInfo::GetProfileDexFileBaseKey(const std::string& dex_location) {
   DCHECK(!dex_location.empty());
   size_t last_sep_index = dex_location.find_last_of('/');
   if (last_sep_index == std::string::npos) {
@@ -160,10 +170,6 @@
     DCHECK(last_sep_index < dex_location.size());
     return dex_location.substr(last_sep_index + 1);
   }
-
-  // TODO(calin): append the RuntimeInstructionSet to the key so we can capture arch-dependent data.
-  // This requires a bit of work as the ProfileSaver and various tests rely on this being a
-  // static public method.
 }
 
 bool ProfileCompilationInfo::AddMethodIndex(MethodHotness::Flag flags, const MethodReference& ref) {
@@ -1875,7 +1881,7 @@
 
   for (uint16_t i = 0; i < number_of_dex_files; i++) {
     std::string dex_location = DexFileLoader::GetMultiDexLocation(i, base_dex_location.c_str());
-    std::string profile_key = GetProfileDexFileKey(dex_location);
+    std::string profile_key = info.GetProfileDexFileKey(dex_location);
 
     for (uint16_t m = 0; m < number_of_methods; m++) {
       uint16_t method_idx = rand() % max_method;
diff --git a/libprofile/profile/profile_compilation_info.h b/libprofile/profile/profile_compilation_info.h
index a6013e1..3b4aade 100644
--- a/libprofile/profile/profile_compilation_info.h
+++ b/libprofile/profile/profile_compilation_info.h
@@ -98,7 +98,7 @@
 
     bool MatchesDex(const DexFile* dex_file) const {
       return dex_checksum == dex_file->GetLocationChecksum() &&
-           dex_location == GetProfileDexFileKey(dex_file->GetLocation());
+           dex_location == GetProfileDexFileBaseKey(dex_file->GetLocation());
     }
 
     std::string dex_location;
@@ -427,7 +427,12 @@
       const std::vector<const DexFile*>& dex_files_) const;
 
   // Return the profile key associated with the given dex location.
-  static std::string GetProfileDexFileKey(const std::string& dex_location);
+  std::string GetProfileDexFileKey(const std::string& dex_location) const;
+  // Return the base profile key associated with the given dex location. The base profile key
+  // is solely constructed based on the dex location (as opposed to the one produced by
+  // GetProfileDexFileKey which may include additional metadata like architecture or source
+  // package name)
+  static std::string GetProfileDexFileBaseKey(const std::string& dex_location);
 
   // Generate a test profile which will contain a percentage of the total maximum
   // number of methods and classes (method_ratio and class_ratio).
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index cad6e59..c16b26c 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -102,7 +102,7 @@
       }
     }
     for (uint16_t i = 0; i < number_of_classes; i++) {
-      ASSERT_TRUE(info->AddClassIndex(ProfileCompilationInfo::GetProfileDexFileKey(dex_location1),
+      ASSERT_TRUE(info->AddClassIndex(info->GetProfileDexFileKey(dex_location1),
                                       dex_location_checksum1,
                                       dex::TypeIndex(i),
                                       number_of_methods1));
@@ -1234,9 +1234,9 @@
 
   ProfileCompilationInfo::ProfileLoadFilterFn filter_fn =
       [&d1, &d2](const std::string& dex_location, uint32_t checksum) -> bool {
-          return (dex_location == ProfileCompilationInfo::GetProfileDexFileKey(d1.GetLocation())
+          return (dex_location == ProfileCompilationInfo::GetProfileDexFileBaseKey(d1.GetLocation())
               && checksum == d1.GetLocationChecksum())
-              || (dex_location == ProfileCompilationInfo::GetProfileDexFileKey(d2.GetLocation())
+              || (dex_location == ProfileCompilationInfo::GetProfileDexFileBaseKey(d2.GetLocation())
               && checksum == d2.GetLocationChecksum());
         };
 
diff --git a/profman/profman.cc b/profman/profman.cc
index 9c13b0d..cc7ff0e 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -408,7 +408,7 @@
     auto process_fn = [profile_filter_keys](std::unique_ptr<const DexFile>&& dex_file) {
       // Store the profile key of the location instead of the location itself.
       // This will make the matching in the profile filter method much easier.
-      profile_filter_keys->emplace(ProfileCompilationInfo::GetProfileDexFileKey(
+      profile_filter_keys->emplace(ProfileCompilationInfo::GetProfileDexFileBaseKey(
           dex_file->GetLocation()), dex_file->GetLocationChecksum());
     };
     return OpenApkFilesFromLocations(process_fn);
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index a560dff..a5a895d 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -719,12 +719,14 @@
   if (options.GetProfileBootClassPath()) {
     std::set<std::string> code_paths_keys;
     for (const std::string& location : code_paths) {
-      code_paths_keys.insert(ProfileCompilationInfo::GetProfileDexFileKey(location));
+      // Use the profile base key for checking file uniqueness (as it is constructed solely based
+      // on the location and ignores other metadata like architecture).
+      code_paths_keys.insert(ProfileCompilationInfo::GetProfileDexFileBaseKey(location));
     }
     for (const DexFile* dex_file : runtime->GetClassLinker()->GetBootClassPath()) {
       // Don't check ShouldProfileLocation since the boot class path may be speed compiled.
       const std::string& location = dex_file->GetLocation();
-      const std::string key = ProfileCompilationInfo::GetProfileDexFileKey(location);
+      const std::string key = ProfileCompilationInfo::GetProfileDexFileBaseKey(location);
       VLOG(profiler) << "Registering boot dex file " << location;
       if (code_paths_keys.find(key) != code_paths_keys.end()) {
         LOG(WARNING) << "Boot class path location key conflicts with code path " << location;
diff --git a/runtime/jit/profiling_info_test.cc b/runtime/jit/profiling_info_test.cc
index f695c8f..724bce3 100644
--- a/runtime/jit/profiling_info_test.cc
+++ b/runtime/jit/profiling_info_test.cc
@@ -204,7 +204,7 @@
         dex_pc_data.AddClass(dex_profile_index, class_ref.TypeIndex());
         if (dex_profile_index >= offline_pmi.dex_references.size()) {
           // This is a new dex.
-          const std::string& dex_key = ProfileCompilationInfo::GetProfileDexFileKey(
+          const std::string& dex_key = ProfileCompilationInfo::GetProfileDexFileBaseKey(
               class_ref.dex_file->GetLocation());
           offline_pmi.dex_references.emplace_back(dex_key,
                                                   class_ref.dex_file->GetLocationChecksum(),