Refactor some profiling info functions

Deleted profile_compilation_info-inl.h

Added a new helper class MethodHotness to reduce the number of
required getters for reading method hotness, startup, and post
startup booleans.

Test: test-art-host
Bug: 62040831

Change-Id: I799a38e2bea6177ba5816c54524f4ccacedba772
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 91b58e1..51446d4 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1002,7 +1002,7 @@
   }
   // Compile only hot methods, it is the profile saver's job to decide what startup methods to mark
   // as hot.
-  bool result = profile_compilation_info_->ContainsHotMethod(method_ref);
+  bool result = profile_compilation_info_->GetMethodHotness(method_ref).IsHot();
 
   if (kDebugProfileGuidedCompilation) {
     LOG(INFO) << "[ProfileGuidedCompilation] "
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 4b979d8..85d8b12 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -239,14 +239,10 @@
 
     ProfileCompilationInfo info;
     for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
-      profile_info_.AddMethodIndex(dex_file->GetLocation(),
-                                   dex_file->GetLocationChecksum(),
-                                   1,
-                                   dex_file->NumMethodIds());
-      profile_info_.AddMethodIndex(dex_file->GetLocation(),
-                                   dex_file->GetLocationChecksum(),
-                                   2,
-                                   dex_file->NumMethodIds());
+      profile_info_.AddMethodIndex(ProfileCompilationInfo::MethodHotness::kFlagHot,
+                                   MethodReference(dex_file.get(), 1));
+      profile_info_.AddMethodIndex(ProfileCompilationInfo::MethodHotness::kFlagHot,
+                                   MethodReference(dex_file.get(), 2));
     }
     return &profile_info_;
   }
diff --git a/dexlayout/dex_visualize.cc b/dexlayout/dex_visualize.cc
index d279bcb..4b46341 100644
--- a/dexlayout/dex_visualize.cc
+++ b/dexlayout/dex_visualize.cc
@@ -174,7 +174,7 @@
                       ProfileCompilationInfo* profile_info) {
     if (profile_info != nullptr) {
       uint32_t method_idx = method->GetMethodId()->GetIndex();
-      if (!profile_info->ContainsHotMethod(MethodReference(dex_file, method_idx))) {
+      if (!profile_info->GetMethodHotness(MethodReference(dex_file, method_idx)).IsHot()) {
         return;
       }
     }
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 50dda88..f1554fd 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -1557,7 +1557,7 @@
             (method->GetAccessFlags() & kAccConstructor) != 0 &&
             (method->GetAccessFlags() & kAccStatic) != 0;
         const bool method_executed = is_clinit ||
-            info_->IsStartupOrHotMethod(MethodReference(dex_file, method_id->GetIndex()));
+            info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex())).HasAnyFlags();
         if (!method_executed) {
           continue;
         }
@@ -1699,7 +1699,7 @@
             (method->GetAccessFlags() & kAccConstructor) != 0 &&
             (method->GetAccessFlags() & kAccStatic) != 0;
         const bool is_method_executed =
-            info_->IsStartupOrHotMethod(MethodReference(dex_file, method_id->GetIndex()));
+            info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex())).HasAnyFlags();
         CodeItemKind code_item_kind = CodeItemKind::kMethodNotExecuted;
         if (is_clinit) {
           code_item_kind = CodeItemKind::kMethodClinit;
diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc
index 6fe8eeb..43c531d 100644
--- a/dexlayout/dexlayout_test.cc
+++ b/dexlayout/dexlayout_test.cc
@@ -334,24 +334,23 @@
     size_t profile_methods = 0;
     size_t profile_classes = 0;
     ProfileCompilationInfo pfi;
-    std::vector<ProfileMethodInfo> pmis;
     std::set<DexCacheResolvedClasses> classes;
     for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
       for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) {
+        uint8_t flags = 0u;
+
         if ((i & 3) != 0) {
-          pfi.AddMethodIndex(dex_location,
-                             dex_file->GetLocationChecksum(),
-                             i,
-                             dex_file->NumMethodIds());
+          flags |= ProfileCompilationInfo::MethodHotness::kFlagHot;
           ++profile_methods;
         } else if ((i & 2) != 0) {
-          pfi.AddSampledMethod(/*startup*/true,
-                               dex_location,
-                               dex_file->GetLocationChecksum(),
-                               i,
-                               dex_file->NumMethodIds());
+          flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup;
           ++profile_methods;
         }
+        pfi.AddMethodIndex(static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
+                           dex_location,
+                           dex_file->GetLocationChecksum(),
+                           /*dex_method_idx*/i,
+                           dex_file->NumMethodIds());
       }
       DexCacheResolvedClasses cur_classes(dex_location,
                                           dex_location,
@@ -366,7 +365,7 @@
       }
       classes.insert(cur_classes);
     }
-    pfi.AddMethodsAndClasses(pmis, classes);
+    pfi.AddClasses(classes);
     // Write to provided file.
     std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str()));
     ASSERT_TRUE(file != nullptr);
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index ccf9ac6..9e2ab39 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -86,14 +86,19 @@
                          const ScratchFile& profile,
                          ProfileCompilationInfo* info) {
     std::string dex_location = "location1" + id;
+    using Hotness = ProfileCompilationInfo::MethodHotness;
     for (uint32_t idx : hot_methods) {
-      info->AddMethodIndex(dex_location, checksum, idx, number_of_methods);
+      info->AddMethodIndex(Hotness::kFlagHot, dex_location, checksum, idx, number_of_methods);
     }
     for (uint32_t idx : startup_methods) {
-      info->AddSampledMethod(/*startup*/true, dex_location, checksum, idx, number_of_methods);
+      info->AddMethodIndex(Hotness::kFlagStartup, dex_location, checksum, idx, number_of_methods);
     }
     for (uint32_t idx : post_startup_methods) {
-      info->AddSampledMethod(/*startup*/false, dex_location, checksum, idx, number_of_methods);
+      info->AddMethodIndex(Hotness::kFlagPostStartup,
+                           dex_location,
+                           checksum,
+                           idx,
+                           number_of_methods);
     }
     ASSERT_TRUE(info->Save(GetFd(profile)));
     ASSERT_EQ(0, profile.GetFile()->Flush());
@@ -609,7 +614,7 @@
           info.GetMethod(method.GetDexFile()->GetLocation(),
                          method.GetDexFile()->GetLocationChecksum(),
                          method.GetDexMethodIndex());
-      ASSERT_TRUE(pmi != nullptr);
+      ASSERT_TRUE(pmi != nullptr) << method.PrettyMethod();
     }
   }
   EXPECT_GT(method_count, 0u);
diff --git a/profman/profman.cc b/profman/profman.cc
index adef0d0..b46378e 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -779,13 +779,15 @@
             if (it.GetMethodCodeItemOffset() != 0) {
               // Add all of the methods that have code to the profile.
               const uint32_t method_idx = it.GetMemberIndex();
-              methods.push_back(ProfileMethodInfo(dex_file, method_idx));
+              methods.push_back(ProfileMethodInfo(MethodReference(dex_file, method_idx)));
             }
             it.Next();
           }
         }
       }
-      profile->AddMethodsAndClasses(methods, resolved_class_set);
+      // TODO: Check return values?
+      profile->AddMethods(methods);
+      profile->AddClasses(resolved_class_set);
       return true;
     }
 
@@ -833,28 +835,23 @@
       }
       inline_caches.emplace_back(dex_pc, is_missing_types, classes);
     }
-    ProfileMethodInfo pmi(class_ref.dex_file, method_index, inline_caches);
+    MethodReference ref(class_ref.dex_file, method_index);
     if (is_hot) {
-      profile->AddMethod(pmi);
+      profile->AddMethod(ProfileMethodInfo(ref, inline_caches));
     }
+    uint32_t flags = 0;
+    using Hotness = ProfileCompilationInfo::MethodHotness;
     if (is_startup) {
-      if (!profile->AddSampledMethod(/*is_startup*/ true,
-                                     pmi.dex_file->GetLocation(),
-                                     pmi.dex_file->GetLocationChecksum(),
-                                     method_index,
-                                     pmi.dex_file->NumMethodIds())) {
-        return false;
-      }
-      DCHECK(profile->IsStartupOrHotMethod(MethodReference(pmi.dex_file, method_index)));
+      flags |= Hotness::kFlagStartup;
     }
     if (is_post_startup) {
-      if (!profile->AddSampledMethod(/*is_startup*/ false,
-                                     pmi.dex_file->GetLocation(),
-                                     pmi.dex_file->GetLocationChecksum(),
-                                     method_index,
-                                     pmi.dex_file->NumMethodIds())) {
+      flags |= Hotness::kFlagPostStartup;
+    }
+    if (flags != 0) {
+      if (!profile->AddMethodIndex(static_cast<Hotness::Flag>(flags), ref)) {
         return false;
       }
+      DCHECK(profile->GetMethodHotness(ref).HasAnyFlags());
     }
     return true;
   }
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 2744c4f..ebee165 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1309,7 +1309,7 @@
     // If the inline cache is empty the compiler will generate a regular invoke virtual/interface.
     if (method->GetCounter() < jit_compile_threshold) {
       methods.emplace_back(/*ProfileMethodInfo*/
-          dex_file, method->GetDexMethodIndex(), inline_caches);
+          MethodReference(dex_file, method->GetDexMethodIndex()), inline_caches);
       continue;
     }
 
@@ -1366,7 +1366,7 @@
       }
     }
     methods.emplace_back(/*ProfileMethodInfo*/
-        dex_file, method->GetDexMethodIndex(), inline_caches);
+        MethodReference(dex_file, method->GetDexMethodIndex()), inline_caches);
   }
 }
 
diff --git a/runtime/jit/profile_compilation_info-inl.h b/runtime/jit/profile_compilation_info-inl.h
deleted file mode 100644
index b71a95e..0000000
--- a/runtime/jit/profile_compilation_info-inl.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_INL_H_
-#define ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_INL_H_
-
-#include "profile_compilation_info.h"
-
-namespace art {
-
-template <class Iterator>
-inline bool ProfileCompilationInfo::AddMethodsForDex(bool startup,
-                                                     bool hot,
-                                                     const DexFile* dex_file,
-                                                     Iterator index_begin,
-                                                     Iterator index_end) {
-  DexFileData* data = GetOrAddDexFileData(dex_file);
-  if (data == nullptr) {
-    return false;
-  }
-  for (auto it = index_begin; it != index_end; ++it) {
-    DCHECK_LT(*it, data->num_method_ids);
-    data->AddSampledMethod(startup, *it);
-    if (hot) {
-      data->FindOrAddMethod(*it);
-    }
-  }
-  return true;
-}
-
-template <class Iterator>
-inline bool ProfileCompilationInfo::AddClassesForDex(const DexFile* dex_file,
-                                                     Iterator index_begin,
-                                                     Iterator index_end) {
-  DexFileData* data = GetOrAddDexFileData(dex_file);
-  if (data == nullptr) {
-    return false;
-  }
-  data->class_set.insert(index_begin, index_end);
-  return true;
-}
-
-}  // namespace art
-
-#endif  // ART_RUNTIME_JIT_PROFILE_COMPILATION_INFO_INL_H_
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index a67fb38..306eb16 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -68,6 +68,10 @@
 static_assert(InlineCache::kIndividualCacheSize < kIsMissingTypesEncoding,
               "InlineCache::kIndividualCacheSize is larger than expected");
 
+static bool ChecksumMatch(uint32_t dex_file_checksum, uint32_t checksum) {
+  return kDebugIgnoreChecksum || dex_file_checksum == checksum;
+}
+
 ProfileCompilationInfo::ProfileCompilationInfo(ArenaPool* custom_arena_pool)
     : default_arena_pool_(),
       arena_(custom_arena_pool),
@@ -132,29 +136,40 @@
   }
 }
 
-bool ProfileCompilationInfo::AddSampledMethod(bool startup,
-                                              const std::string& dex_location,
-                                              uint32_t checksum,
-                                              uint16_t method_idx,
-                                              uint32_t num_method_ids) {
+bool ProfileCompilationInfo::AddMethodIndex(MethodHotness::Flag flags, const MethodReference& ref) {
+  DexFileData* data = GetOrAddDexFileData(ref.dex_file);
+  if (data == nullptr) {
+    return false;
+  }
+  data->AddMethod(flags, ref.dex_method_index);
+  return true;
+}
+
+bool ProfileCompilationInfo::AddMethodIndex(MethodHotness::Flag flags,
+                                            const std::string& dex_location,
+                                            uint32_t checksum,
+                                            uint16_t method_idx,
+                                            uint32_t num_method_ids) {
   DexFileData* data = GetOrAddDexFileData(GetProfileDexFileKey(dex_location),
                                           checksum,
                                           num_method_ids);
   if (data == nullptr) {
     return false;
   }
-  data->AddSampledMethod(startup, method_idx);
+  data->AddMethod(flags, method_idx);
   return true;
 }
 
-bool ProfileCompilationInfo::AddMethodsAndClasses(
-    const std::vector<ProfileMethodInfo>& methods,
-    const std::set<DexCacheResolvedClasses>& resolved_classes) {
+bool ProfileCompilationInfo::AddMethods(const std::vector<ProfileMethodInfo>& methods) {
   for (const ProfileMethodInfo& method : methods) {
     if (!AddMethod(method)) {
       return false;
     }
   }
+  return true;
+}
+
+bool ProfileCompilationInfo::AddClasses(const std::set<DexCacheResolvedClasses>& resolved_classes) {
   for (const DexCacheResolvedClasses& dex_cache : resolved_classes) {
     if (!AddResolvedClasses(dex_cache)) {
       return false;
@@ -533,8 +548,7 @@
   DCHECK_EQ(num_method_ids, result->num_method_ids);
 
   // Check that the checksum matches.
-  // This may different if for example the dex file was updated and
-  // we had a record of the old one.
+  // This may different if for example the dex file was updated and we had a record of the old one.
   if (result->checksum != checksum) {
     LOG(WARNING) << "Checksum mismatch for dex " << profile_key;
     return nullptr;
@@ -543,7 +557,9 @@
 }
 
 const ProfileCompilationInfo::DexFileData* ProfileCompilationInfo::FindDexData(
-      const std::string& profile_key) const {
+      const std::string& profile_key,
+      uint32_t checksum,
+      bool verify_checksum) const {
   const auto profile_index_it = profile_key_map_.find(profile_key);
   if (profile_index_it == profile_key_map_.end()) {
     return nullptr;
@@ -551,6 +567,9 @@
 
   uint8_t profile_index = profile_index_it->second;
   const DexFileData* result = info_[profile_index];
+  if (verify_checksum && !ChecksumMatch(result->checksum, checksum)) {
+    return nullptr;
+  }
   DCHECK_EQ(profile_key, result->profile_key);
   DCHECK_EQ(profile_index, result->profile_index);
   return result;
@@ -567,17 +586,6 @@
   return true;
 }
 
-bool ProfileCompilationInfo::AddMethodIndex(const std::string& dex_location,
-                                            uint32_t dex_checksum,
-                                            uint16_t method_index,
-                                            uint32_t num_method_ids) {
-  return AddMethod(dex_location,
-                   dex_checksum,
-                   method_index,
-                   num_method_ids,
-                   OfflineProfileMethodInfo(nullptr));
-}
-
 bool ProfileCompilationInfo::AddMethod(const std::string& dex_location,
                                        uint32_t dex_checksum,
                                        uint16_t method_index,
@@ -630,11 +638,11 @@
 }
 
 bool ProfileCompilationInfo::AddMethod(const ProfileMethodInfo& pmi) {
-  DexFileData* const data = GetOrAddDexFileData(pmi.dex_file);
+  DexFileData* const data = GetOrAddDexFileData(pmi.ref.dex_file);
   if (data == nullptr) {  // checksum mismatch
     return false;
   }
-  InlineCacheMap* inline_cache = data->FindOrAddMethod(pmi.dex_method_index);
+  InlineCacheMap* inline_cache = data->FindOrAddMethod(pmi.ref.dex_method_index);
 
   for (const ProfileMethodInfo::ProfileInlineCache& cache : pmi.inline_caches) {
     if (cache.is_missing_types) {
@@ -1143,7 +1151,9 @@
   // Note that the number of elements should be very small, so this should not
   // be a performance issue.
   for (const DexFileData* other_dex_data : other.info_) {
-    const DexFileData* dex_data = FindDexData(other_dex_data->profile_key);
+    const DexFileData* dex_data = FindDexData(other_dex_data->profile_key,
+                                              0u,
+                                              /* verify_checksum */ false);
     if ((dex_data != nullptr) && (dex_data->checksum != other_dex_data->checksum)) {
       LOG(WARNING) << "Checksum mismatch for dex " << other_dex_data->profile_key;
       return false;
@@ -1174,7 +1184,8 @@
 
   // Merge the actual profile data.
   for (const DexFileData* other_dex_data : other.info_) {
-    DexFileData* dex_data = const_cast<DexFileData*>(FindDexData(other_dex_data->profile_key));
+    DexFileData* dex_data = const_cast<DexFileData*>(FindDexData(other_dex_data->profile_key,
+                                                                 other_dex_data->checksum));
     DCHECK(dex_data != nullptr);
 
     // Merge the classes.
@@ -1203,86 +1214,41 @@
       }
     }
 
-    // Merge the bitmaps.
+    // Merge the method bitmaps.
     dex_data->MergeBitmap(*other_dex_data);
   }
   return true;
 }
 
-static bool ChecksumMatch(uint32_t dex_file_checksum, uint32_t checksum) {
-  return kDebugIgnoreChecksum || dex_file_checksum == checksum;
-}
-
-static bool ChecksumMatch(const DexFile& dex_file, uint32_t checksum) {
-  return ChecksumMatch(dex_file.GetLocationChecksum(), checksum);
-}
-
-bool ProfileCompilationInfo::IsStartupOrHotMethod(const MethodReference& method_ref) const {
-  return IsStartupOrHotMethod(method_ref.dex_file->GetLocation(),
-                              method_ref.dex_file->GetLocationChecksum(),
-                              method_ref.dex_method_index);
-}
-
 const ProfileCompilationInfo::DexFileData* ProfileCompilationInfo::FindDexData(
     const DexFile* dex_file) const {
-  const DexFileData* dex_data = FindDexData(GetProfileDexFileKey(dex_file->GetLocation()));
-  if (dex_data == nullptr || !ChecksumMatch(*dex_file, dex_data->checksum)) {
-    return nullptr;
-  }
-  return dex_data;
+  return FindDexData(GetProfileDexFileKey(dex_file->GetLocation()),
+                     dex_file->GetLocationChecksum());
 }
 
-bool ProfileCompilationInfo::IsStartupOrHotMethod(const std::string& dex_location,
-                                                  uint32_t dex_checksum,
-                                                  uint16_t dex_method_index) const {
-  const DexFileData* dex_data = FindDexData(GetProfileDexFileKey(dex_location));
-  if (dex_data == nullptr || !ChecksumMatch(dex_checksum, dex_data->checksum)) {
-    return false;
-  }
-  if (dex_data->HasSampledMethod(/*startup*/ true, dex_method_index)) {
-    return true;
-  }
-  const MethodMap& methods = dex_data->method_map;
-  const auto method_it = methods.find(dex_method_index);
-  return method_it != methods.end();
-}
-
-bool ProfileCompilationInfo::ContainsSampledMethod(bool startup,
-                                                   const MethodReference& method_ref) const {
+ProfileCompilationInfo::MethodHotness ProfileCompilationInfo::GetMethodHotness(
+    const MethodReference& method_ref) const {
   const DexFileData* dex_data = FindDexData(method_ref.dex_file);
-  if (dex_data == nullptr) {
-    return false;
-  }
-  return dex_data->HasSampledMethod(startup, method_ref.dex_method_index);
+  return dex_data != nullptr
+      ? dex_data->GetHotnessInfo(method_ref.dex_method_index)
+      : MethodHotness();
 }
 
-bool ProfileCompilationInfo::ContainsHotMethod(const MethodReference& method_ref) const {
-  return FindMethod(method_ref.dex_file->GetLocation(),
-                    method_ref.dex_file->GetLocationChecksum(),
-                    method_ref.dex_method_index) != nullptr;
+ProfileCompilationInfo::MethodHotness ProfileCompilationInfo::GetMethodHotness(
+    const std::string& dex_location,
+    uint32_t dex_checksum,
+    uint16_t dex_method_index) const {
+  const DexFileData* dex_data = FindDexData(GetProfileDexFileKey(dex_location), dex_checksum);
+  return dex_data != nullptr ? dex_data->GetHotnessInfo(dex_method_index) : MethodHotness();
 }
 
-const ProfileCompilationInfo::InlineCacheMap*
-ProfileCompilationInfo::FindMethod(const std::string& dex_location,
-                                   uint32_t dex_checksum,
-                                   uint16_t dex_method_index) const {
-  const DexFileData* dex_data = FindDexData(GetProfileDexFileKey(dex_location));
-  if (dex_data != nullptr) {
-    if (!ChecksumMatch(dex_checksum, dex_data->checksum)) {
-      return nullptr;
-    }
-    const MethodMap& methods = dex_data->method_map;
-    const auto method_it = methods.find(dex_method_index);
-    return method_it == methods.end() ? nullptr : &(method_it->second);
-  }
-  return nullptr;
-}
 
 std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> ProfileCompilationInfo::GetMethod(
-      const std::string& dex_location,
-      uint32_t dex_checksum,
-      uint16_t dex_method_index) const {
-  const InlineCacheMap* inline_caches = FindMethod(dex_location, dex_checksum, dex_method_index);
+    const std::string& dex_location,
+    uint32_t dex_checksum,
+    uint16_t dex_method_index) const {
+  MethodHotness hotness(GetMethodHotness(dex_location, dex_checksum, dex_method_index));
+  const InlineCacheMap* inline_caches = hotness.GetInlineCacheMap();
   if (inline_caches == nullptr) {
     return nullptr;
   }
@@ -1301,11 +1267,8 @@
 
 
 bool ProfileCompilationInfo::ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const {
-  const DexFileData* dex_data = FindDexData(GetProfileDexFileKey(dex_file.GetLocation()));
+  const DexFileData* dex_data = FindDexData(&dex_file);
   if (dex_data != nullptr) {
-    if (!ChecksumMatch(dex_file, dex_data->checksum)) {
-      return false;
-    }
     const ArenaSet<dex::TypeIndex>& classes = dex_data->class_set;
     return classes.find(type_idx) != classes.end();
   }
@@ -1404,7 +1367,8 @@
     while (true) {
       os << "\n\t" << (startup ? "startup methods: " : "post startup methods: ");
       for (uint32_t method_idx = 0; method_idx < dex_data->num_method_ids; ++method_idx) {
-        if (dex_data->HasSampledMethod(startup, method_idx)) {
+        MethodHotness hotness_info(dex_data->GetHotnessInfo(method_idx));
+        if (startup ? hotness_info.IsStartup() : hotness_info.IsPostStartup()) {
           os << method_idx << ", ";
         }
       }
@@ -1432,19 +1396,19 @@
     /*out*/std::set<uint16_t>* startup_method_set,
     /*out*/std::set<uint16_t>* post_startup_method_method_set) const {
   std::set<std::string> ret;
-  std::string profile_key = GetProfileDexFileKey(dex_file.GetLocation());
-  const DexFileData* dex_data = FindDexData(profile_key);
-  if (dex_data == nullptr || dex_data->checksum != dex_file.GetLocationChecksum()) {
+  const DexFileData* dex_data = FindDexData(&dex_file);
+  if (dex_data == nullptr) {
     return false;
   }
   for (const auto& it : dex_data->method_map) {
     hot_method_set->insert(it.first);
   }
   for (uint32_t method_idx = 0; method_idx < dex_data->num_method_ids; ++method_idx) {
-    if (dex_data->HasSampledMethod(/*startup*/ true, method_idx)) {
+    MethodHotness hotness = dex_data->GetHotnessInfo(method_idx);
+    if (hotness.IsStartup()) {
       startup_method_set->insert(method_idx);
     }
-    if (dex_data->HasSampledMethod(/*startup*/ false, method_idx)) {
+    if (hotness.IsPostStartup()) {
       post_startup_method_method_set->insert(method_idx);
     }
   }
@@ -1529,7 +1493,11 @@
       if (m < (number_of_methods / kFavorSplit)) {
         method_idx %= kFavorFirstN;
       }
-      info.AddMethodIndex(profile_key, 0, method_idx, max_method);
+      info.AddMethodIndex(MethodHotness::kFlagHot,
+                          profile_key,
+                          /*method_idx*/ 0,
+                          method_idx,
+                          max_method);
     }
 
     for (uint16_t c = 0; c < number_of_classes; c++) {
@@ -1558,14 +1526,14 @@
       if (std::rand() % 2 != 0) {
         info.AddClassIndex(location,
                            checksum,
-                           dex::TypeIndex(dex_file->GetClassDef(i).class_idx_),
+                           dex_file->GetClassDef(i).class_idx_,
                            dex_file->NumMethodIds());
       }
     }
     for (uint32_t i = 0; i < dex_file->NumMethodIds(); ++i) {
       // Randomly add a method from the dex file (with 50% chance).
       if (std::rand() % 2 != 0) {
-        info.AddMethodIndex(location, checksum, i, dex_file->NumMethodIds());
+        info.AddMethodIndex(MethodHotness::kFlagHot, MethodReference(dex_file.get(), i));
       }
     }
   }
diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h
index 7bcaffb..cdcfe3e 100644
--- a/runtime/jit/profile_compilation_info.h
+++ b/runtime/jit/profile_compilation_info.h
@@ -49,19 +49,14 @@
     const std::vector<TypeReference> classes;
   };
 
-  ProfileMethodInfo(const DexFile* dex, uint32_t method_index)
-      : dex_file(dex), dex_method_index(method_index) {}
+  explicit ProfileMethodInfo(MethodReference reference) : ref(reference) {}
 
-  ProfileMethodInfo(const DexFile* dex,
-                    uint32_t method_index,
-                    const std::vector<ProfileInlineCache>& caches)
-      : dex_file(dex),
-        dex_method_index(method_index),
+  ProfileMethodInfo(MethodReference reference, const std::vector<ProfileInlineCache>& caches)
+      : ref(reference),
         inline_caches(caches) {}
 
-  const DexFile* dex_file;
-  const uint32_t dex_method_index;
-  const std::vector<ProfileInlineCache> inline_caches;
+  MethodReference ref;
+  std::vector<ProfileInlineCache> inline_caches;
 };
 
 /**
@@ -173,6 +168,49 @@
   // Maps a method dex index to its inline cache.
   using MethodMap = ArenaSafeMap<uint16_t, InlineCacheMap>;
 
+  // Profile method hotness information for a single method. Also includes a pointer to the inline
+  // cache map.
+  class MethodHotness {
+   public:
+    enum Flag {
+      kFlagHot = 0x1,
+      kFlagStartup = 0x2,
+      kFlagPostStartup = 0x4,
+    };
+
+    bool IsHot() const {
+      return (flags_ & kFlagHot) != 0;
+    }
+
+    bool IsStartup() const {
+      return (flags_ & kFlagStartup) != 0;
+    }
+
+    bool IsPostStartup() const {
+      return (flags_ & kFlagPostStartup) != 0;
+    }
+
+    void AddFlag(Flag flag) {
+      flags_ |= flag;
+    }
+
+    bool HasAnyFlags() const {
+      return flags_ != 0;
+    }
+
+    const InlineCacheMap* GetInlineCacheMap() const {
+      return inline_cache_map_;
+    }
+
+    void SetInlineCacheMap(const InlineCacheMap* info) {
+      inline_cache_map_ = info;
+    }
+
+   private:
+    const InlineCacheMap* inline_cache_map_ = nullptr;
+    uint8_t flags_ = 0;
+  };
+
   // Encodes the full set of inline caches for a given method.
   // The dex_references vector is indexed according to the ClassReference::dex_profile_index.
   // i.e. the dex file of any ClassReference present in the inline caches can be found at
@@ -193,40 +231,53 @@
 
   ~ProfileCompilationInfo();
 
-  // Add the given methods and classes to the current profile object.
-  bool AddMethodsAndClasses(const std::vector<ProfileMethodInfo>& methods,
-                            const std::set<DexCacheResolvedClasses>& resolved_classes);
+  // Add the given methods to the current profile object.
+  bool AddMethods(const std::vector<ProfileMethodInfo>& methods);
 
-  // Iterator is type for ids not class defs.
+  // Add the given classes to the current profile object.
+  bool AddClasses(const std::set<DexCacheResolvedClasses>& resolved_classes);
+
+  // Add multiple type ids for classes in a single dex file. Iterator is for type_ids not
+  // class_defs.
   template <class Iterator>
-  bool AddClassesForDex(const DexFile* dex_file, Iterator index_begin, Iterator index_end);
+  bool AddClassesForDex(const DexFile* dex_file, Iterator index_begin, Iterator index_end) {
+    DexFileData* data = GetOrAddDexFileData(dex_file);
+    if (data == nullptr) {
+      return false;
+    }
+    data->class_set.insert(index_begin, index_end);
+    return true;
+  }
 
-  // Add a method index to the profile (without inline caches).
-  bool AddMethodIndex(const std::string& dex_location,
+  // Add a method index to the profile (without inline caches). The method flags determine if it is
+  // hot, startup, or post startup, or a combination of the previous.
+  bool AddMethodIndex(MethodHotness::Flag flags,
+                      const std::string& dex_location,
                       uint32_t checksum,
                       uint16_t method_idx,
                       uint32_t num_method_ids);
+  bool AddMethodIndex(MethodHotness::Flag flags, const MethodReference& ref);
 
   // Add a method to the profile using its online representation (containing runtime structures).
   bool AddMethod(const ProfileMethodInfo& pmi);
 
-  // Add methods that have samples but are are not necessarily hot. These are partitioned into two
-  // possibly intersecting sets startup and post startup. Sampled methods are used for layout but
-  // not necessarily determining what gets compiled.
-  bool AddSampledMethod(bool startup,
-                        const std::string& dex_location,
-                        uint32_t checksum,
-                        uint16_t method_idx,
-                        uint32_t num_method_ids);
-
   // Bulk add sampled methods and/or hot methods for a single dex, fast since it only has one
   // GetOrAddDexFileData call.
   template <class Iterator>
-  ALWAYS_INLINE bool AddMethodsForDex(bool startup,
-                                      bool hot,
-                                      const DexFile* dex_file,
-                                      Iterator index_begin,
-                                      Iterator index_end);
+  bool AddMethodsForDex(MethodHotness::Flag flags,
+                        const DexFile* dex_file,
+                        Iterator index_begin,
+                        Iterator index_end) {
+    DexFileData* data = GetOrAddDexFileData(dex_file);
+    if (data == nullptr) {
+      return false;
+    }
+    for (Iterator it = index_begin; it != index_end; ++it) {
+      DCHECK_LT(*it, data->num_method_ids);
+      data->AddMethod(flags, *it);
+    }
+    return true;
+  }
 
   // Load profile information from the given file descriptor.
   // If the current profile is non-empty the load will fail.
@@ -253,18 +304,11 @@
   // Return the number of resolved classes that were profiled.
   uint32_t GetNumberOfResolvedClasses() const;
 
-  // Return true if the method reference is a hot or startup method in the profiling info.
-  bool IsStartupOrHotMethod(const MethodReference& method_ref) const;
-  bool IsStartupOrHotMethod(const std::string& dex_location,
-                            uint32_t dex_checksum,
-                            uint16_t dex_method_index) const;
-
-  // Return true if the method reference iS present and hot in the profiling info.
-  bool ContainsHotMethod(const MethodReference& method_ref) const;
-
-
-  // Return true if the profile contains a startup or post startup method.
-  bool ContainsSampledMethod(bool startup, const MethodReference& method_ref) const;
+  // Returns the profile method info for a given method reference.
+  MethodHotness GetMethodHotness(const MethodReference& method_ref) const;
+  MethodHotness GetMethodHotness(const std::string& dex_location,
+                                 uint32_t dex_checksum,
+                                 uint16_t dex_method_index) const;
 
   // Return true if the class's type is present in the profiling info.
   bool ContainsClass(const DexFile& dex_file, dex::TypeIndex type_idx) const;
@@ -373,12 +417,18 @@
     }
 
     // Mark a method as executed at least once.
-    void AddSampledMethod(bool startup, size_t index) {
-      method_bitmap.StoreBit(MethodBitIndex(startup, index), true);
-    }
-
-    bool HasSampledMethod(bool startup, size_t index) const {
-      return method_bitmap.LoadBit(MethodBitIndex(startup, index));
+    void AddMethod(MethodHotness::Flag flags, size_t index) {
+      if ((flags & MethodHotness::kFlagStartup) != 0) {
+        method_bitmap.StoreBit(MethodBitIndex(/*startup*/ true, index), /*value*/ true);
+      }
+      if ((flags & MethodHotness::kFlagPostStartup) != 0) {
+        method_bitmap.StoreBit(MethodBitIndex(/*startup*/ false, index), /*value*/ true);
+      }
+      if ((flags & MethodHotness::kFlagHot) != 0) {
+        method_map.FindOrAdd(
+            index,
+            InlineCacheMap(std::less<uint16_t>(), arena_->Adapter(kArenaAllocProfile)));
+      }
     }
 
     void MergeBitmap(const DexFileData& other) {
@@ -388,6 +438,22 @@
       }
     }
 
+    MethodHotness GetHotnessInfo(uint32_t dex_method_index) const {
+      MethodHotness ret;
+      if (method_bitmap.LoadBit(MethodBitIndex(/*startup*/ true, dex_method_index))) {
+        ret.AddFlag(MethodHotness::kFlagStartup);
+      }
+      if (method_bitmap.LoadBit(MethodBitIndex(/*startup*/ false, dex_method_index))) {
+        ret.AddFlag(MethodHotness::kFlagPostStartup);
+      }
+      auto it = method_map.find(dex_method_index);
+      if (it != method_map.end()) {
+        ret.SetInlineCacheMap(&it->second);
+        ret.AddFlag(MethodHotness::kFlagHot);
+      }
+      return ret;
+    }
+
     // The arena used to allocate new inline cache maps.
     ArenaAllocator* arena_;
     // The profile key this data belongs to.
@@ -456,19 +522,15 @@
   // Add all classes from the given dex cache to the the profile.
   bool AddResolvedClasses(const DexCacheResolvedClasses& classes);
 
-  // Search for the given method in the profile.
-  // If found, its inline cache map is returned, otherwise the method returns null.
-  const InlineCacheMap* FindMethod(const std::string& dex_location,
-                                   uint32_t dex_checksum,
-                                   uint16_t dex_method_index) const;
-
   // Encode the known dex_files into a vector. The index of a dex_reference will
   // be the same as the profile index of the dex file (used to encode the ClassReferences).
   void DexFileToProfileIndex(/*out*/std::vector<DexReference>* dex_references) const;
 
   // Return the dex data associated with the given profile key or null if the profile
   // doesn't contain the key.
-  const DexFileData* FindDexData(const std::string& profile_key) const;
+  const DexFileData* FindDexData(const std::string& profile_key,
+                                 uint32_t checksum,
+                                 bool verify_checksum = true) const;
 
   // Return the dex data associated with the given dex file or null if the profile doesn't contain
   // the key or the checksum mismatches.
diff --git a/runtime/jit/profile_compilation_info_test.cc b/runtime/jit/profile_compilation_info_test.cc
index 5528366..c3a3415 100644
--- a/runtime/jit/profile_compilation_info_test.cc
+++ b/runtime/jit/profile_compilation_info_test.cc
@@ -25,13 +25,15 @@
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
 #include "handle_scope-inl.h"
-#include "jit/profile_compilation_info-inl.h"
+#include "jit/profile_compilation_info.h"
 #include "linear_alloc.h"
 #include "scoped_thread_state_change-inl.h"
 #include "type_reference.h"
 
 namespace art {
 
+using Hotness = ProfileCompilationInfo::MethodHotness;
+
 static constexpr size_t kMaxMethodIds = 65535;
 
 class ProfileCompilationInfoTest : public CommonRuntimeTest {
@@ -63,7 +65,11 @@
                  uint32_t checksum,
                  uint16_t method_index,
                  ProfileCompilationInfo* info) {
-    return info->AddMethodIndex(dex_location, checksum, method_index, kMaxMethodIds);
+    return info->AddMethodIndex(Hotness::kFlagHot,
+                                dex_location,
+                                checksum,
+                                method_index,
+                                kMaxMethodIds);
   }
 
   bool AddMethod(const std::string& dex_location,
@@ -76,9 +82,11 @@
 
   bool AddClass(const std::string& dex_location,
                 uint32_t checksum,
-                uint16_t class_index,
+                dex::TypeIndex type_index,
                 ProfileCompilationInfo* info) {
-    return info->AddMethodIndex(dex_location, checksum, class_index, kMaxMethodIds);
+    DexCacheResolvedClasses classes(dex_location, dex_location, checksum, kMaxMethodIds);
+    classes.AddClass(type_index);
+    return info->AddClasses({classes});
   }
 
   uint32_t GetFd(const ScratchFile& file) {
@@ -93,9 +101,10 @@
     std::vector<ProfileMethodInfo> profile_methods;
     ScopedObjectAccess soa(Thread::Current());
     for (ArtMethod* method : methods) {
-      profile_methods.emplace_back(method->GetDexFile(), method->GetDexMethodIndex());
+      profile_methods.emplace_back(
+          MethodReference(method->GetDexFile(), method->GetDexMethodIndex()));
     }
-    if (!info.AddMethodsAndClasses(profile_methods, resolved_classes)) {
+    if (!info.AddMethods(profile_methods) || !info.AddClasses(resolved_classes)) {
       return false;
     }
     if (info.GetNumberOfMethods() != profile_methods.size()) {
@@ -151,17 +160,14 @@
         std::vector<TypeReference> classes;
         caches.emplace_back(dex_pc, /*is_missing_types*/true, classes);
       }
-      ProfileMethodInfo pmi(method->GetDexFile(),
-                            method->GetDexMethodIndex(),
+      ProfileMethodInfo pmi(MethodReference(method->GetDexFile(),
+                                            method->GetDexMethodIndex()),
                             caches);
       profile_methods.push_back(pmi);
       profile_methods_map->Put(method, pmi);
     }
 
-    if (!info.AddMethodsAndClasses(profile_methods, std::set<DexCacheResolvedClasses>())) {
-      return false;
-    }
-    if (info.GetNumberOfMethods() != profile_methods.size()) {
+    if (!info.AddMethods(profile_methods) || info.GetNumberOfMethods() != profile_methods.size()) {
       return false;
     }
     return info.Save(filename, nullptr);
@@ -298,8 +304,8 @@
   {
     ScopedObjectAccess soa(self);
     for (ArtMethod* m : main_methods) {
-      ASSERT_TRUE(info1.ContainsHotMethod(
-          MethodReference(m->GetDexFile(), m->GetDexMethodIndex())));
+      ASSERT_TRUE(info1.GetMethodHotness(
+          MethodReference(m->GetDexFile(), m->GetDexMethodIndex())).IsHot());
     }
   }
 
@@ -316,11 +322,11 @@
     ScopedObjectAccess soa(self);
     for (ArtMethod* m : main_methods) {
       ASSERT_TRUE(
-          info2.ContainsHotMethod(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())));
+          info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())).IsHot());
     }
     for (ArtMethod* m : second_methods) {
       ASSERT_TRUE(
-          info2.ContainsHotMethod(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())));
+          info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())).IsHot());
     }
   }
 }
@@ -392,8 +398,8 @@
   }
   // Save the maximum number of classes
   for (uint16_t i = 0; i < std::numeric_limits<uint16_t>::max(); i++) {
-    ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, /* class_idx */ i, &saved_info));
-    ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, /* class_idx */ i, &saved_info));
+    ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, dex::TypeIndex(i), &saved_info));
+    ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &saved_info));
   }
 
   ASSERT_TRUE(saved_info.Save(GetFd(profile)));
@@ -667,7 +673,7 @@
     ScopedObjectAccess soa(self);
     for (ArtMethod* m : main_methods) {
       ASSERT_TRUE(
-          info.ContainsHotMethod(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())));
+          info.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex())).IsHot());
       const ProfileMethodInfo& pmi = profile_methods_map.find(m)->second;
       std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> offline_pmi =
           info.GetMethod(m->GetDexFile()->GetLocation(),
@@ -857,18 +863,19 @@
   static constexpr size_t kChecksum2 = 4321;
   static const std::string kDex1 = "dex1";
   static const std::string kDex2 = "dex2";
-  test_info.AddSampledMethod(true, kDex1, kChecksum1, 1, kNumMethods);
-  test_info.AddSampledMethod(true, kDex1, kChecksum1, 5, kNumMethods);
-  test_info.AddSampledMethod(false, kDex2, kChecksum2, 1, kNumMethods);
-  test_info.AddSampledMethod(false, kDex2, kChecksum2, 5, kNumMethods);
+  test_info.AddMethodIndex(Hotness::kFlagStartup, kDex1, kChecksum1, 1, kNumMethods);
+  test_info.AddMethodIndex(Hotness::kFlagPostStartup, kDex1, kChecksum1, 5, kNumMethods);
+  test_info.AddMethodIndex(Hotness::kFlagStartup, kDex2, kChecksum2, 2, kNumMethods);
+  test_info.AddMethodIndex(Hotness::kFlagPostStartup, kDex2, kChecksum2, 4, kNumMethods);
   auto run_test = [](const ProfileCompilationInfo& info) {
-    EXPECT_FALSE(info.IsStartupOrHotMethod(kDex1, kChecksum1, 0));
-    EXPECT_TRUE(info.IsStartupOrHotMethod(kDex1, kChecksum1, 1));
-    EXPECT_FALSE(info.IsStartupOrHotMethod(kDex1, kChecksum1, 3));
-    EXPECT_TRUE(info.IsStartupOrHotMethod(kDex1, kChecksum1, 5));
-    EXPECT_FALSE(info.IsStartupOrHotMethod(kDex1, kChecksum1, 6));
-    EXPECT_FALSE(info.IsStartupOrHotMethod(kDex2, kChecksum2, 5));
-    EXPECT_FALSE(info.IsStartupOrHotMethod(kDex2, kChecksum2, 5));
+    EXPECT_FALSE(info.GetMethodHotness(kDex1, kChecksum1, 2).HasAnyFlags());
+    EXPECT_FALSE(info.GetMethodHotness(kDex1, kChecksum1, 4).HasAnyFlags());
+    EXPECT_TRUE(info.GetMethodHotness(kDex1, kChecksum1, 1).IsStartup());
+    EXPECT_FALSE(info.GetMethodHotness(kDex1, kChecksum1, 3).IsStartup());
+    EXPECT_TRUE(info.GetMethodHotness(kDex1, kChecksum1, 5).IsPostStartup());
+    EXPECT_FALSE(info.GetMethodHotness(kDex1, kChecksum1, 6).IsStartup());
+    EXPECT_TRUE(info.GetMethodHotness(kDex2, kChecksum2, 2).IsStartup());
+    EXPECT_TRUE(info.GetMethodHotness(kDex2, kChecksum2, 4).IsPostStartup());
   };
   run_test(test_info);
 
@@ -884,13 +891,13 @@
   run_test(loaded_info);
 
   // Test that the bitmap gets merged properly.
-  EXPECT_FALSE(test_info.IsStartupOrHotMethod(kDex1, kChecksum1, 11));
+  EXPECT_FALSE(test_info.GetMethodHotness(kDex1, kChecksum1, 11).IsStartup());
   {
     ProfileCompilationInfo merge_info;
-    merge_info.AddSampledMethod(true, kDex1, kChecksum1, 11, kNumMethods);
+    merge_info.AddMethodIndex(Hotness::kFlagStartup, kDex1, kChecksum1, 11, kNumMethods);
     test_info.MergeWith(merge_info);
   }
-  EXPECT_TRUE(test_info.IsStartupOrHotMethod(kDex1, kChecksum1, 11));
+  EXPECT_TRUE(test_info.GetMethodHotness(kDex1, kChecksum1, 11).IsStartup());
 
   // Test bulk adding.
   {
@@ -900,39 +907,36 @@
     std::vector<uint16_t> startup_methods = {1, 2};
     std::vector<uint16_t> post_methods = {0, 2, 6};
     ASSERT_GE(dex->NumMethodIds(), 7u);
-    info.AddMethodsForDex(/*startup*/true,
-                          /*hot*/true,
+    info.AddMethodsForDex(static_cast<Hotness::Flag>(Hotness::kFlagHot | Hotness::kFlagStartup),
                           dex.get(),
                           hot_methods.begin(),
                           hot_methods.end());
-    info.AddMethodsForDex(/*startup*/true,
-                          /*hot*/false,
+    info.AddMethodsForDex(Hotness::kFlagStartup,
                           dex.get(),
                           startup_methods.begin(),
                           startup_methods.end());
-    info.AddMethodsForDex(/*startup*/false,
-                          /*hot*/false,
+    info.AddMethodsForDex(Hotness::kFlagPostStartup,
                           dex.get(),
                           post_methods.begin(),
                           post_methods.end());
     for (uint16_t id : hot_methods) {
-      EXPECT_TRUE(info.ContainsHotMethod(MethodReference(dex.get(), id)));
-      EXPECT_TRUE(info.ContainsSampledMethod(/*startup*/true, MethodReference(dex.get(), id)));
+      EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), id)).IsHot());
+      EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), id)).IsStartup());
     }
     for (uint16_t id : startup_methods) {
-      EXPECT_TRUE(info.ContainsSampledMethod(/*startup*/true, MethodReference(dex.get(), id)));
+      EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), id)).IsStartup());
     }
     for (uint16_t id : post_methods) {
-      EXPECT_TRUE(info.ContainsSampledMethod(/*startup*/false, MethodReference(dex.get(), id)));
+      EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), id)).IsPostStartup());
     }
-    EXPECT_TRUE(info.ContainsSampledMethod(/*startup*/false, MethodReference(dex.get(), 6)));
+    EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), 6)).IsPostStartup());
     // Check that methods that shouldn't have been touched are OK.
-    EXPECT_FALSE(info.ContainsHotMethod(MethodReference(dex.get(), 0)));
-    EXPECT_FALSE(info.ContainsHotMethod(MethodReference(dex.get(), 2)));
-    EXPECT_FALSE(info.ContainsHotMethod(MethodReference(dex.get(), 4)));
-    EXPECT_FALSE(info.ContainsSampledMethod(/*startup*/false, MethodReference(dex.get(), 1)));
-    EXPECT_FALSE(info.ContainsSampledMethod(/*startup*/true, MethodReference(dex.get(), 4)));
-    EXPECT_FALSE(info.ContainsSampledMethod(/*startup*/true, MethodReference(dex.get(), 6)));
+    EXPECT_TRUE(info.GetMethodHotness(MethodReference(dex.get(), 0)).HasAnyFlags());
+    EXPECT_FALSE(info.GetMethodHotness(MethodReference(dex.get(), 4)).HasAnyFlags());
+    EXPECT_FALSE(info.GetMethodHotness(MethodReference(dex.get(), 7)).HasAnyFlags());
+    EXPECT_FALSE(info.GetMethodHotness(MethodReference(dex.get(), 1)).IsPostStartup());
+    EXPECT_FALSE(info.GetMethodHotness(MethodReference(dex.get(), 4)).IsStartup());
+    EXPECT_FALSE(info.GetMethodHotness(MethodReference(dex.get(), 6)).IsStartup());
   }
 }
 
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index c6c46de..94363c6 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -34,7 +34,7 @@
 #include "gc/collector_type.h"
 #include "gc/gc_cause.h"
 #include "gc/scoped_gc_critical_section.h"
-#include "jit/profile_compilation_info-inl.h"
+#include "jit/profile_compilation_info.h"
 #include "oat_file_manager.h"
 #include "scoped_thread_state_change-inl.h"
 
@@ -275,6 +275,7 @@
 
   MutexLock mu(self, *Locks::profiler_lock_);
   uint64_t total_number_of_profile_entries_cached = 0;
+  using Hotness = ProfileCompilationInfo::MethodHotness;
 
   for (const auto& it : tracked_dex_base_locations_) {
     std::set<DexCacheResolvedClasses> resolved_classes_for_location;
@@ -289,19 +290,18 @@
       const DexFile* const dex_file = pair.first;
       if (locations.find(dex_file->GetBaseLocation()) != locations.end()) {
         const MethodReferenceCollection::IndexVector& indices = pair.second;
-        cached_info->AddMethodsForDex(/*startup*/ true,
-                                      /*hot*/ true,
-                                      dex_file,
-                                      indices.begin(),
-                                      indices.end());
+        cached_info->AddMethodsForDex(
+            static_cast<Hotness::Flag>(Hotness::kFlagHot | Hotness::kFlagStartup),
+            dex_file,
+            indices.begin(),
+            indices.end());
       }
     }
     for (const auto& pair : startup_methods.GetMap()) {
       const DexFile* const dex_file = pair.first;
       if (locations.find(dex_file->GetBaseLocation()) != locations.end()) {
         const MethodReferenceCollection::IndexVector& indices = pair.second;
-        cached_info->AddMethodsForDex(/*startup*/ true,
-                                      /*hot*/ false,
+        cached_info->AddMethodsForDex(Hotness::kFlagStartup,
                                       dex_file,
                                       indices.begin(),
                                       indices.end());
@@ -373,7 +373,7 @@
       uint64_t last_save_number_of_methods = info.GetNumberOfMethods();
       uint64_t last_save_number_of_classes = info.GetNumberOfResolvedClasses();
 
-      info.AddMethodsAndClasses(profile_methods, std::set<DexCacheResolvedClasses>());
+      info.AddMethods(profile_methods);
       auto profile_cache_it = profile_cache_.find(filename);
       if (profile_cache_it != profile_cache_.end()) {
         info.MergeWith(*(profile_cache_it->second));
@@ -681,7 +681,7 @@
     if (!info.Load(profile, /*clear_if_invalid*/false)) {
       return false;
     }
-    return info.ContainsHotMethod(MethodReference(dex_file, method_idx));
+    return info.GetMethodHotness(MethodReference(dex_file, method_idx)).HasAnyFlags();
   }
   return false;
 }