diff --git a/libprofile/profile/profile_compilation_info_test.cc b/libprofile/profile/profile_compilation_info_test.cc
index ead7cba..42c3320 100644
--- a/libprofile/profile/profile_compilation_info_test.cc
+++ b/libprofile/profile/profile_compilation_info_test.cc
@@ -17,20 +17,14 @@
 #include <gtest/gtest.h>
 #include <stdio.h>
 
-#include "art_method-inl.h"
+#include "base/arena_allocator.h"
+#include "base/common_art_test.h"
 #include "base/unix_file/fd_file.h"
-#include "class_linker-inl.h"
-#include "common_runtime_test.h"
 #include "dex/dex_file.h"
 #include "dex/dex_file_loader.h"
 #include "dex/method_reference.h"
 #include "dex/type_reference.h"
-#include "handle_scope-inl.h"
-#include "linear_alloc.h"
-#include "mirror/class-inl.h"
-#include "mirror/class_loader.h"
 #include "profile/profile_compilation_info.h"
-#include "scoped_thread_state_change-inl.h"
 #include "ziparchive/zip_writer.h"
 
 namespace art {
@@ -39,31 +33,14 @@
 
 static constexpr size_t kMaxMethodIds = 65535;
 
-class ProfileCompilationInfoTest : public CommonRuntimeTest {
+class ProfileCompilationInfoTest : public CommonArtTest {
  public:
-  void PostRuntimeCreate() OVERRIDE {
-    allocator_.reset(new ArenaAllocator(Runtime::Current()->GetArenaPool()));
+  void SetUp() OVERRIDE {
+    CommonArtTest::SetUp();
+    allocator_.reset(new ArenaAllocator(&pool_));
   }
 
  protected:
-  std::vector<ArtMethod*> GetVirtualMethods(jobject class_loader,
-                                            const std::string& clazz) {
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    Thread* self = Thread::Current();
-    ScopedObjectAccess soa(self);
-    StackHandleScope<1> hs(self);
-    Handle<mirror::ClassLoader> h_loader(
-        hs.NewHandle(self->DecodeJObject(class_loader)->AsClassLoader()));
-    ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
-
-    const auto pointer_size = class_linker->GetImagePointerSize();
-    std::vector<ArtMethod*> methods;
-    for (auto& m : klass->GetVirtualMethods(pointer_size)) {
-      methods.push_back(&m);
-    }
-    return methods;
-  }
-
   bool AddMethod(const std::string& dex_location,
                  uint32_t checksum,
                  uint16_t method_index,
@@ -97,89 +74,6 @@
     return static_cast<uint32_t>(file.GetFd());
   }
 
-  bool SaveProfilingInfo(
-      const std::string& filename,
-      const std::vector<ArtMethod*>& methods,
-      const std::set<DexCacheResolvedClasses>& resolved_classes,
-      Hotness::Flag flags) {
-    ProfileCompilationInfo info;
-    std::vector<ProfileMethodInfo> profile_methods;
-    ScopedObjectAccess soa(Thread::Current());
-    for (ArtMethod* method : methods) {
-      profile_methods.emplace_back(
-          MethodReference(method->GetDexFile(), method->GetDexMethodIndex()));
-    }
-    if (!info.AddMethods(profile_methods, flags) || !info.AddClasses(resolved_classes)) {
-      return false;
-    }
-    if (info.GetNumberOfMethods() != profile_methods.size()) {
-      return false;
-    }
-    ProfileCompilationInfo file_profile;
-    if (!file_profile.Load(filename, false)) {
-      return false;
-    }
-    if (!info.MergeWith(file_profile)) {
-      return false;
-    }
-
-    return info.Save(filename, nullptr);
-  }
-
-  // Saves the given art methods to a profile backed by 'filename' and adds
-  // some fake inline caches to it. The added inline caches are returned in
-  // the out map `profile_methods_map`.
-  bool SaveProfilingInfoWithFakeInlineCaches(
-      const std::string& filename,
-      const std::vector<ArtMethod*>& methods,
-      Hotness::Flag flags,
-      /*out*/ SafeMap<ArtMethod*, ProfileMethodInfo>* profile_methods_map) {
-    ProfileCompilationInfo info;
-    std::vector<ProfileMethodInfo> profile_methods;
-    ScopedObjectAccess soa(Thread::Current());
-    for (ArtMethod* method : methods) {
-      std::vector<ProfileMethodInfo::ProfileInlineCache> caches;
-      // Monomorphic
-      for (uint16_t dex_pc = 0; dex_pc < 11; dex_pc++) {
-        std::vector<TypeReference> classes;
-        classes.emplace_back(method->GetDexFile(), dex::TypeIndex(0));
-        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
-      }
-      // Polymorphic
-      for (uint16_t dex_pc = 11; dex_pc < 22; dex_pc++) {
-        std::vector<TypeReference> classes;
-        for (uint16_t k = 0; k < InlineCache::kIndividualCacheSize / 2; k++) {
-          classes.emplace_back(method->GetDexFile(), dex::TypeIndex(k));
-        }
-        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
-      }
-      // Megamorphic
-      for (uint16_t dex_pc = 22; dex_pc < 33; dex_pc++) {
-        std::vector<TypeReference> classes;
-        for (uint16_t k = 0; k < 2 * InlineCache::kIndividualCacheSize; k++) {
-          classes.emplace_back(method->GetDexFile(), dex::TypeIndex(k));
-        }
-        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
-      }
-      // Missing types
-      for (uint16_t dex_pc = 33; dex_pc < 44; dex_pc++) {
-        std::vector<TypeReference> classes;
-        caches.emplace_back(dex_pc, /*is_missing_types*/true, classes);
-      }
-      ProfileMethodInfo pmi(MethodReference(method->GetDexFile(),
-                                            method->GetDexMethodIndex()),
-                            caches);
-      profile_methods.push_back(pmi);
-      profile_methods_map->Put(method, pmi);
-    }
-
-    if (!info.AddMethods(profile_methods, flags)
-        || info.GetNumberOfMethods() != profile_methods.size()) {
-      return false;
-    }
-    return info.Save(filename, nullptr);
-  }
-
   // Creates an inline cache which will be destructed at the end of the test.
   ProfileCompilationInfo::InlineCacheMap* CreateInlineCacheMap() {
     used_inline_caches.emplace_back(new ProfileCompilationInfo::InlineCacheMap(
@@ -187,35 +81,6 @@
     return used_inline_caches.back().get();
   }
 
-  ProfileCompilationInfo::OfflineProfileMethodInfo ConvertProfileMethodInfo(
-        const ProfileMethodInfo& pmi) {
-    ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap();
-    ProfileCompilationInfo::OfflineProfileMethodInfo offline_pmi(ic_map);
-    SafeMap<DexFile*, uint8_t> dex_map;  // dex files to profile index
-    for (const auto& inline_cache : pmi.inline_caches) {
-      ProfileCompilationInfo::DexPcData& dex_pc_data =
-          ic_map->FindOrAdd(
-              inline_cache.dex_pc, ProfileCompilationInfo::DexPcData(allocator_.get()))->second;
-      if (inline_cache.is_missing_types) {
-        dex_pc_data.SetIsMissingTypes();
-      }
-      for (const auto& class_ref : inline_cache.classes) {
-        uint8_t dex_profile_index = dex_map.FindOrAdd(const_cast<DexFile*>(class_ref.dex_file),
-                                                      static_cast<uint8_t>(dex_map.size()))->second;
-        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(
-              class_ref.dex_file->GetLocation());
-          offline_pmi.dex_references.emplace_back(dex_key,
-                                                  class_ref.dex_file->GetLocationChecksum(),
-                                                  class_ref.dex_file->NumMethodIds());
-        }
-      }
-    }
-    return offline_pmi;
-  }
-
   // Creates an offline profile used for testing inline caches.
   ProfileCompilationInfo::OfflineProfileMethodInfo GetOfflineProfileMethodInfo() {
     ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap();
@@ -261,7 +126,7 @@
     ProfileCompilationInfo::InlineCacheMap* ic_map =
         const_cast<ProfileCompilationInfo::InlineCacheMap*>(pmi->inline_caches);
     for (auto it : *ic_map) {
-      for (uint16_t k = 0; k <= 2 * InlineCache::kIndividualCacheSize; k++) {
+      for (uint16_t k = 0; k <= 2 * ProfileCompilationInfo::kIndividualInlineCacheSize; k++) {
         it.second.AddClass(0, dex::TypeIndex(k));
       }
     }
@@ -327,6 +192,7 @@
   static constexpr int kProfileMagicSize = 4;
   static constexpr int kProfileVersionSize = 4;
 
+  MallocArenaPool pool_;
   std::unique_ptr<ArenaAllocator> allocator_;
 
   // Cache of inline caches generated during tests.
@@ -335,61 +201,6 @@
   std::vector<std::unique_ptr<ProfileCompilationInfo::InlineCacheMap>> used_inline_caches;
 };
 
-TEST_F(ProfileCompilationInfoTest, SaveArtMethods) {
-  ScratchFile profile;
-
-  Thread* self = Thread::Current();
-  jobject class_loader;
-  {
-    ScopedObjectAccess soa(self);
-    class_loader = LoadDex("ProfileTestMultiDex");
-  }
-  ASSERT_NE(class_loader, nullptr);
-
-  // Save virtual methods from Main.
-  std::set<DexCacheResolvedClasses> resolved_classes;
-  std::vector<ArtMethod*> main_methods = GetVirtualMethods(class_loader, "LMain;");
-  ASSERT_TRUE(SaveProfilingInfo(
-      profile.GetFilename(), main_methods, resolved_classes, Hotness::kFlagPostStartup));
-
-  // Check that what we saved is in the profile.
-  ProfileCompilationInfo info1;
-  ASSERT_TRUE(info1.Load(GetFd(profile)));
-  ASSERT_EQ(info1.GetNumberOfMethods(), main_methods.size());
-  {
-    ScopedObjectAccess soa(self);
-    for (ArtMethod* m : main_methods) {
-      Hotness h = info1.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
-      ASSERT_TRUE(h.IsHot());
-      ASSERT_TRUE(h.IsPostStartup());
-    }
-  }
-
-  // Save virtual methods from Second.
-  std::vector<ArtMethod*> second_methods = GetVirtualMethods(class_loader, "LSecond;");
-  ASSERT_TRUE(SaveProfilingInfo(
-    profile.GetFilename(), second_methods, resolved_classes, Hotness::kFlagStartup));
-
-  // Check that what we saved is in the profile (methods form Main and Second).
-  ProfileCompilationInfo info2;
-  ASSERT_TRUE(profile.GetFile()->ResetOffset());
-  ASSERT_TRUE(info2.Load(GetFd(profile)));
-  ASSERT_EQ(info2.GetNumberOfMethods(), main_methods.size() + second_methods.size());
-  {
-    ScopedObjectAccess soa(self);
-    for (ArtMethod* m : main_methods) {
-      Hotness h = info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
-      ASSERT_TRUE(h.IsHot());
-      ASSERT_TRUE(h.IsPostStartup());
-    }
-    for (ArtMethod* m : second_methods) {
-      Hotness h = info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
-      ASSERT_TRUE(h.IsHot());
-      ASSERT_TRUE(h.IsStartup());
-    }
-  }
-}
-
 TEST_F(ProfileCompilationInfoTest, SaveFd) {
   ScratchFile profile;
 
@@ -722,48 +533,6 @@
   ASSERT_TRUE(*loaded_pmi1 == pmi_extra);
 }
 
-TEST_F(ProfileCompilationInfoTest, SaveArtMethodsWithInlineCaches) {
-  ScratchFile profile;
-
-  Thread* self = Thread::Current();
-  jobject class_loader;
-  {
-    ScopedObjectAccess soa(self);
-    class_loader = LoadDex("ProfileTestMultiDex");
-  }
-  ASSERT_NE(class_loader, nullptr);
-
-  // Save virtual methods from Main.
-  std::set<DexCacheResolvedClasses> resolved_classes;
-  std::vector<ArtMethod*> main_methods = GetVirtualMethods(class_loader, "LMain;");
-
-  SafeMap<ArtMethod*, ProfileMethodInfo> profile_methods_map;
-  ASSERT_TRUE(SaveProfilingInfoWithFakeInlineCaches(
-      profile.GetFilename(), main_methods, Hotness::kFlagStartup, &profile_methods_map));
-
-  // Check that what we saved is in the profile.
-  ProfileCompilationInfo info;
-  ASSERT_TRUE(info.Load(GetFd(profile)));
-  ASSERT_EQ(info.GetNumberOfMethods(), main_methods.size());
-  {
-    ScopedObjectAccess soa(self);
-    for (ArtMethod* m : main_methods) {
-      Hotness h = info.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
-      ASSERT_TRUE(h.IsHot());
-      ASSERT_TRUE(h.IsStartup());
-      const ProfileMethodInfo& pmi = profile_methods_map.find(m)->second;
-      std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> offline_pmi =
-          info.GetMethod(m->GetDexFile()->GetLocation(),
-                         m->GetDexFile()->GetLocationChecksum(),
-                         m->GetDexMethodIndex());
-      ASSERT_TRUE(offline_pmi != nullptr);
-      ProfileCompilationInfo::OfflineProfileMethodInfo converted_pmi =
-          ConvertProfileMethodInfo(pmi);
-      ASSERT_EQ(converted_pmi, *offline_pmi);
-    }
-  }
-}
-
 TEST_F(ProfileCompilationInfoTest, InvalidChecksumInInlineCache) {
   ScratchFile profile;
 
diff --git a/runtime/Android.bp b/runtime/Android.bp
index b276c81..777a1fc 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -574,6 +574,7 @@
         "interpreter/safe_math_test.cc",
         "interpreter/unstarted_runtime_test.cc",
         "jdwp/jdwp_options_test.cc",
+        "jit/profiling_info_test.cc",
         "jni/java_vm_ext_test.cc",
         "method_handles_test.cc",
         "mirror/dex_cache_test.cc",
diff --git a/runtime/jit/profiling_info_test.cc b/runtime/jit/profiling_info_test.cc
new file mode 100644
index 0000000..106a80a
--- /dev/null
+++ b/runtime/jit/profiling_info_test.cc
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <gtest/gtest.h>
+#include <stdio.h>
+
+#include "art_method-inl.h"
+#include "base/unix_file/fd_file.h"
+#include "class_linker-inl.h"
+#include "common_runtime_test.h"
+#include "dex/dex_file.h"
+#include "dex/dex_file_loader.h"
+#include "dex/method_reference.h"
+#include "dex/type_reference.h"
+#include "handle_scope-inl.h"
+#include "linear_alloc.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "profile/profile_compilation_info.h"
+#include "scoped_thread_state_change-inl.h"
+#include "ziparchive/zip_writer.h"
+
+namespace art {
+
+using Hotness = ProfileCompilationInfo::MethodHotness;
+
+static constexpr size_t kMaxMethodIds = 65535;
+
+class ProfileCompilationInfoTest : public CommonRuntimeTest {
+ public:
+  void PostRuntimeCreate() OVERRIDE {
+    allocator_.reset(new ArenaAllocator(Runtime::Current()->GetArenaPool()));
+  }
+
+ protected:
+  std::vector<ArtMethod*> GetVirtualMethods(jobject class_loader,
+                                            const std::string& clazz) {
+    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+    Thread* self = Thread::Current();
+    ScopedObjectAccess soa(self);
+    StackHandleScope<1> hs(self);
+    Handle<mirror::ClassLoader> h_loader(
+        hs.NewHandle(self->DecodeJObject(class_loader)->AsClassLoader()));
+    ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader);
+
+    const auto pointer_size = class_linker->GetImagePointerSize();
+    std::vector<ArtMethod*> methods;
+    for (auto& m : klass->GetVirtualMethods(pointer_size)) {
+      methods.push_back(&m);
+    }
+    return methods;
+  }
+
+  bool AddMethod(const std::string& dex_location,
+                 uint32_t checksum,
+                 uint16_t method_index,
+                 ProfileCompilationInfo* info) {
+    return info->AddMethodIndex(Hotness::kFlagHot,
+                                dex_location,
+                                checksum,
+                                method_index,
+                                kMaxMethodIds);
+  }
+
+  bool AddMethod(const std::string& dex_location,
+                 uint32_t checksum,
+                 uint16_t method_index,
+                 const ProfileCompilationInfo::OfflineProfileMethodInfo& pmi,
+                 ProfileCompilationInfo* info) {
+    return info->AddMethod(
+        dex_location, checksum, method_index, kMaxMethodIds, pmi, Hotness::kFlagPostStartup);
+  }
+
+  bool AddClass(const std::string& dex_location,
+                uint32_t checksum,
+                dex::TypeIndex type_index,
+                ProfileCompilationInfo* info) {
+    DexCacheResolvedClasses classes(dex_location, dex_location, checksum, kMaxMethodIds);
+    classes.AddClass(type_index);
+    return info->AddClasses({classes});
+  }
+
+  uint32_t GetFd(const ScratchFile& file) {
+    return static_cast<uint32_t>(file.GetFd());
+  }
+
+  bool SaveProfilingInfo(
+      const std::string& filename,
+      const std::vector<ArtMethod*>& methods,
+      const std::set<DexCacheResolvedClasses>& resolved_classes,
+      Hotness::Flag flags) {
+    ProfileCompilationInfo info;
+    std::vector<ProfileMethodInfo> profile_methods;
+    ScopedObjectAccess soa(Thread::Current());
+    for (ArtMethod* method : methods) {
+      profile_methods.emplace_back(
+          MethodReference(method->GetDexFile(), method->GetDexMethodIndex()));
+    }
+    if (!info.AddMethods(profile_methods, flags) || !info.AddClasses(resolved_classes)) {
+      return false;
+    }
+    if (info.GetNumberOfMethods() != profile_methods.size()) {
+      return false;
+    }
+    ProfileCompilationInfo file_profile;
+    if (!file_profile.Load(filename, false)) {
+      return false;
+    }
+    if (!info.MergeWith(file_profile)) {
+      return false;
+    }
+
+    return info.Save(filename, nullptr);
+  }
+
+  // Saves the given art methods to a profile backed by 'filename' and adds
+  // some fake inline caches to it. The added inline caches are returned in
+  // the out map `profile_methods_map`.
+  bool SaveProfilingInfoWithFakeInlineCaches(
+      const std::string& filename,
+      const std::vector<ArtMethod*>& methods,
+      Hotness::Flag flags,
+      /*out*/ SafeMap<ArtMethod*, ProfileMethodInfo>* profile_methods_map) {
+    ProfileCompilationInfo info;
+    std::vector<ProfileMethodInfo> profile_methods;
+    ScopedObjectAccess soa(Thread::Current());
+    for (ArtMethod* method : methods) {
+      std::vector<ProfileMethodInfo::ProfileInlineCache> caches;
+      // Monomorphic
+      for (uint16_t dex_pc = 0; dex_pc < 11; dex_pc++) {
+        std::vector<TypeReference> classes;
+        classes.emplace_back(method->GetDexFile(), dex::TypeIndex(0));
+        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
+      }
+      // Polymorphic
+      for (uint16_t dex_pc = 11; dex_pc < 22; dex_pc++) {
+        std::vector<TypeReference> classes;
+        for (uint16_t k = 0; k < InlineCache::kIndividualCacheSize / 2; k++) {
+          classes.emplace_back(method->GetDexFile(), dex::TypeIndex(k));
+        }
+        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
+      }
+      // Megamorphic
+      for (uint16_t dex_pc = 22; dex_pc < 33; dex_pc++) {
+        std::vector<TypeReference> classes;
+        for (uint16_t k = 0; k < 2 * InlineCache::kIndividualCacheSize; k++) {
+          classes.emplace_back(method->GetDexFile(), dex::TypeIndex(k));
+        }
+        caches.emplace_back(dex_pc, /*is_missing_types*/false, classes);
+      }
+      // Missing types
+      for (uint16_t dex_pc = 33; dex_pc < 44; dex_pc++) {
+        std::vector<TypeReference> classes;
+        caches.emplace_back(dex_pc, /*is_missing_types*/true, classes);
+      }
+      ProfileMethodInfo pmi(MethodReference(method->GetDexFile(),
+                                            method->GetDexMethodIndex()),
+                            caches);
+      profile_methods.push_back(pmi);
+      profile_methods_map->Put(method, pmi);
+    }
+
+    if (!info.AddMethods(profile_methods, flags)
+        || info.GetNumberOfMethods() != profile_methods.size()) {
+      return false;
+    }
+    return info.Save(filename, nullptr);
+  }
+
+  // Creates an inline cache which will be destructed at the end of the test.
+  ProfileCompilationInfo::InlineCacheMap* CreateInlineCacheMap() {
+    used_inline_caches.emplace_back(new ProfileCompilationInfo::InlineCacheMap(
+        std::less<uint16_t>(), allocator_->Adapter(kArenaAllocProfile)));
+    return used_inline_caches.back().get();
+  }
+
+  ProfileCompilationInfo::OfflineProfileMethodInfo ConvertProfileMethodInfo(
+        const ProfileMethodInfo& pmi) {
+    ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap();
+    ProfileCompilationInfo::OfflineProfileMethodInfo offline_pmi(ic_map);
+    SafeMap<DexFile*, uint8_t> dex_map;  // dex files to profile index
+    for (const auto& inline_cache : pmi.inline_caches) {
+      ProfileCompilationInfo::DexPcData& dex_pc_data =
+          ic_map->FindOrAdd(
+              inline_cache.dex_pc, ProfileCompilationInfo::DexPcData(allocator_.get()))->second;
+      if (inline_cache.is_missing_types) {
+        dex_pc_data.SetIsMissingTypes();
+      }
+      for (const auto& class_ref : inline_cache.classes) {
+        uint8_t dex_profile_index = dex_map.FindOrAdd(const_cast<DexFile*>(class_ref.dex_file),
+                                                      static_cast<uint8_t>(dex_map.size()))->second;
+        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(
+              class_ref.dex_file->GetLocation());
+          offline_pmi.dex_references.emplace_back(dex_key,
+                                                  class_ref.dex_file->GetLocationChecksum(),
+                                                  class_ref.dex_file->NumMethodIds());
+        }
+      }
+    }
+    return offline_pmi;
+  }
+
+  // Cannot sizeof the actual arrays so hard code the values here.
+  // They should not change anyway.
+  static constexpr int kProfileMagicSize = 4;
+  static constexpr int kProfileVersionSize = 4;
+
+  std::unique_ptr<ArenaAllocator> allocator_;
+
+  // Cache of inline caches generated during tests.
+  // This makes it easier to pass data between different utilities and ensure that
+  // caches are destructed at the end of the test.
+  std::vector<std::unique_ptr<ProfileCompilationInfo::InlineCacheMap>> used_inline_caches;
+};
+
+TEST_F(ProfileCompilationInfoTest, SaveArtMethods) {
+  ScratchFile profile;
+
+  Thread* self = Thread::Current();
+  jobject class_loader;
+  {
+    ScopedObjectAccess soa(self);
+    class_loader = LoadDex("ProfileTestMultiDex");
+  }
+  ASSERT_NE(class_loader, nullptr);
+
+  // Save virtual methods from Main.
+  std::set<DexCacheResolvedClasses> resolved_classes;
+  std::vector<ArtMethod*> main_methods = GetVirtualMethods(class_loader, "LMain;");
+  ASSERT_TRUE(SaveProfilingInfo(
+      profile.GetFilename(), main_methods, resolved_classes, Hotness::kFlagPostStartup));
+
+  // Check that what we saved is in the profile.
+  ProfileCompilationInfo info1;
+  ASSERT_TRUE(info1.Load(GetFd(profile)));
+  ASSERT_EQ(info1.GetNumberOfMethods(), main_methods.size());
+  {
+    ScopedObjectAccess soa(self);
+    for (ArtMethod* m : main_methods) {
+      Hotness h = info1.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
+      ASSERT_TRUE(h.IsHot());
+      ASSERT_TRUE(h.IsPostStartup());
+    }
+  }
+
+  // Save virtual methods from Second.
+  std::vector<ArtMethod*> second_methods = GetVirtualMethods(class_loader, "LSecond;");
+  ASSERT_TRUE(SaveProfilingInfo(
+    profile.GetFilename(), second_methods, resolved_classes, Hotness::kFlagStartup));
+
+  // Check that what we saved is in the profile (methods form Main and Second).
+  ProfileCompilationInfo info2;
+  ASSERT_TRUE(profile.GetFile()->ResetOffset());
+  ASSERT_TRUE(info2.Load(GetFd(profile)));
+  ASSERT_EQ(info2.GetNumberOfMethods(), main_methods.size() + second_methods.size());
+  {
+    ScopedObjectAccess soa(self);
+    for (ArtMethod* m : main_methods) {
+      Hotness h = info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
+      ASSERT_TRUE(h.IsHot());
+      ASSERT_TRUE(h.IsPostStartup());
+    }
+    for (ArtMethod* m : second_methods) {
+      Hotness h = info2.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
+      ASSERT_TRUE(h.IsHot());
+      ASSERT_TRUE(h.IsStartup());
+    }
+  }
+}
+
+TEST_F(ProfileCompilationInfoTest, SaveArtMethodsWithInlineCaches) {
+  ScratchFile profile;
+
+  Thread* self = Thread::Current();
+  jobject class_loader;
+  {
+    ScopedObjectAccess soa(self);
+    class_loader = LoadDex("ProfileTestMultiDex");
+  }
+  ASSERT_NE(class_loader, nullptr);
+
+  // Save virtual methods from Main.
+  std::set<DexCacheResolvedClasses> resolved_classes;
+  std::vector<ArtMethod*> main_methods = GetVirtualMethods(class_loader, "LMain;");
+
+  SafeMap<ArtMethod*, ProfileMethodInfo> profile_methods_map;
+  ASSERT_TRUE(SaveProfilingInfoWithFakeInlineCaches(
+      profile.GetFilename(), main_methods, Hotness::kFlagStartup, &profile_methods_map));
+
+  // Check that what we saved is in the profile.
+  ProfileCompilationInfo info;
+  ASSERT_TRUE(info.Load(GetFd(profile)));
+  ASSERT_EQ(info.GetNumberOfMethods(), main_methods.size());
+  {
+    ScopedObjectAccess soa(self);
+    for (ArtMethod* m : main_methods) {
+      Hotness h = info.GetMethodHotness(MethodReference(m->GetDexFile(), m->GetDexMethodIndex()));
+      ASSERT_TRUE(h.IsHot());
+      ASSERT_TRUE(h.IsStartup());
+      const ProfileMethodInfo& pmi = profile_methods_map.find(m)->second;
+      std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> offline_pmi =
+          info.GetMethod(m->GetDexFile()->GetLocation(),
+                         m->GetDexFile()->GetLocationChecksum(),
+                         m->GetDexMethodIndex());
+      ASSERT_TRUE(offline_pmi != nullptr);
+      ProfileCompilationInfo::OfflineProfileMethodInfo converted_pmi =
+          ConvertProfileMethodInfo(pmi);
+      ASSERT_EQ(converted_pmi, *offline_pmi);
+    }
+  }
+}
+
+}  // namespace art
