Add inline caches to offline profiles

Add support for inline caches in profiles:
- extract inline caches from the jit cache when the profile saver
queries the hot methods
- bump profile version to support the new data
- add new tests
- inline caches are only supported for same-apk calls (including
multidex)

Test: m art-test-host-gtest-profile_compilation_info_test
Bug: 32434870
Change-Id: I38b4ca0a54568d2224765ff76023baef1b8fd1a2
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 60ab275..c226a38 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1245,15 +1245,40 @@
 }
 
 void JitCodeCache::GetProfiledMethods(const std::set<std::string>& dex_base_locations,
-                                      std::vector<MethodReference>& methods) {
+                                      std::vector<ProfileMethodInfo>& methods) {
   ScopedTrace trace(__FUNCTION__);
   MutexLock mu(Thread::Current(), lock_);
   for (const ProfilingInfo* info : profiling_infos_) {
     ArtMethod* method = info->GetMethod();
     const DexFile* dex_file = method->GetDexFile();
-    if (ContainsElement(dex_base_locations, dex_file->GetBaseLocation())) {
-      methods.emplace_back(dex_file,  method->GetDexMethodIndex());
+    if (!ContainsElement(dex_base_locations, dex_file->GetBaseLocation())) {
+      // Skip dex files which are not profiled.
+      continue;
     }
+    std::vector<ProfileMethodInfo::ProfileInlineCache> inline_caches;
+    for (size_t i = 0; i < info->number_of_inline_caches_; ++i) {
+      std::vector<ProfileMethodInfo::ProfileClassReference> profile_classes;
+      const InlineCache& cache = info->cache_[i];
+      for (size_t k = 0; k < InlineCache::kIndividualCacheSize; k++) {
+        mirror::Class* cls = cache.classes_[k].Read();
+        if (cls == nullptr) {
+          break;
+        }
+        const DexFile& class_dex_file = cls->GetDexFile();
+        dex::TypeIndex type_index = cls->GetDexTypeIndex();
+        if (ContainsElement(dex_base_locations, class_dex_file.GetBaseLocation())) {
+          // Only consider classes from the same apk (including multidex).
+          profile_classes.emplace_back(/*ProfileMethodInfo::ProfileClassReference*/
+              &class_dex_file, type_index);
+        }
+      }
+      if (!profile_classes.empty()) {
+        inline_caches.emplace_back(/*ProfileMethodInfo::ProfileInlineCache*/
+            cache.dex_pc_, profile_classes);
+      }
+    }
+    methods.emplace_back(/*ProfileMethodInfo*/
+        dex_file, method->GetDexMethodIndex(), inline_caches);
   }
 }