Fix compiler crash due to inline caches and improve docs

Fix a potential crash when extracting the inline caches from the method.
The way we copied the inline cache into a new map was not correct. In
ProfileCompilationInfo::GetMethod() we reused the same profile arena
for allocation which is not thread safe. When compiling with multiple
threads the profile arena could become corrupted due to races.

Address all the comments from the late reviews on the CL which migrates
the profiles to arena storage.

Test: m test-art-host
      compile with speed-profile apps on device
Bug: 37711886
Bug: 62062532
Change-Id: I61af5175bc68b2c7dba77afb3cdff221989cc387
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index b836632..41b9f99 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -32,7 +32,7 @@
 
 class ProfileAssistantTest : public CommonRuntimeTest {
  public:
-  virtual void PostRuntimeCreate() {
+  void PostRuntimeCreate() OVERRIDE {
     arena_.reset(new ArenaAllocator(Runtime::Current()->GetArenaPool()));
   }
 
@@ -72,10 +72,18 @@
     ASSERT_TRUE(profile.GetFile()->ResetOffset());
   }
 
+  // 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>(), arena_->Adapter(kArenaAllocProfile)));
+    return used_inline_caches.back().get();
+  }
+
   ProfileCompilationInfo::OfflineProfileMethodInfo GetOfflineProfileMethodInfo(
         const std::string& dex_location1, uint32_t dex_checksum1,
         const std::string& dex_location2, uint32_t dex_checksum2) {
-    ProfileCompilationInfo::OfflineProfileMethodInfo pmi(arena_.get());
+    ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap();
+    ProfileCompilationInfo::OfflineProfileMethodInfo pmi(ic_map);
     pmi.dex_references.emplace_back(dex_location1, dex_checksum1);
     pmi.dex_references.emplace_back(dex_location2, dex_checksum2);
 
@@ -83,7 +91,7 @@
     for (uint16_t dex_pc = 0; dex_pc < 11; dex_pc++) {
       ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.AddClass(0, dex::TypeIndex(0));
-      pmi.inline_caches.Put(dex_pc, dex_pc_data);
+      ic_map->Put(dex_pc, dex_pc_data);
     }
     // Polymorphic
     for (uint16_t dex_pc = 11; dex_pc < 22; dex_pc++) {
@@ -91,19 +99,19 @@
       dex_pc_data.AddClass(0, dex::TypeIndex(0));
       dex_pc_data.AddClass(1, dex::TypeIndex(1));
 
-      pmi.inline_caches.Put(dex_pc, dex_pc_data);
+      ic_map->Put(dex_pc, dex_pc_data);
     }
     // Megamorphic
     for (uint16_t dex_pc = 22; dex_pc < 33; dex_pc++) {
       ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.SetIsMegamorphic();
-      pmi.inline_caches.Put(dex_pc, dex_pc_data);
+      ic_map->Put(dex_pc, dex_pc_data);
     }
     // Missing types
     for (uint16_t dex_pc = 33; dex_pc < 44; dex_pc++) {
       ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.SetIsMissingTypes();
-      pmi.inline_caches.Put(dex_pc, dex_pc_data);
+      ic_map->Put(dex_pc, dex_pc_data);
     }
 
     return pmi;
@@ -258,8 +266,8 @@
                        method->GetDexFile()->GetLocationChecksum(),
                        method->GetDexMethodIndex());
     ASSERT_TRUE(pmi != nullptr);
-    ASSERT_EQ(pmi->inline_caches.size(), 1u);
-    ProfileCompilationInfo::DexPcData dex_pc_data = pmi->inline_caches.begin()->second;
+    ASSERT_EQ(pmi->inline_caches->size(), 1u);
+    const ProfileCompilationInfo::DexPcData& dex_pc_data = pmi->inline_caches->begin()->second;
 
     ASSERT_EQ(dex_pc_data.is_megamorphic, is_megamorphic);
     ASSERT_EQ(dex_pc_data.is_missing_types, is_missing_types);
@@ -280,6 +288,11 @@
   }
 
   std::unique_ptr<ArenaAllocator> arena_;
+
+  // 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(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
@@ -702,7 +715,7 @@
                        no_inline_cache->GetDexFile()->GetLocationChecksum(),
                        no_inline_cache->GetDexMethodIndex());
     ASSERT_TRUE(pmi_no_inline_cache != nullptr);
-    ASSERT_TRUE(pmi_no_inline_cache->inline_caches.empty());
+    ASSERT_TRUE(pmi_no_inline_cache->inline_caches->empty());
   }
 }