Use arena allocation for profiles

By using our arena allocator we can madvise the memory used during
profile processing right way. jemalloc may defer the release based on
unpredictable native allocation.

The other advantage of arenas is a much simpler way to measure the
memory needed by profiles.

Test: m test-art-host
Test: manual inspection with meminfo and heaptrack
Bug: 37711886

Change-Id: Ib656a8ac63600477ff553831087a83dc40d9c537
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 38254e2..b836632 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -21,6 +21,7 @@
 #include "common_runtime_test.h"
 #include "exec_utils.h"
 #include "jit/profile_compilation_info.h"
+#include "linear_alloc.h"
 #include "mirror/class-inl.h"
 #include "obj_ptr-inl.h"
 #include "profile_assistant.h"
@@ -30,6 +31,11 @@
 namespace art {
 
 class ProfileAssistantTest : public CommonRuntimeTest {
+ public:
+  virtual void PostRuntimeCreate() {
+    arena_.reset(new ArenaAllocator(Runtime::Current()->GetArenaPool()));
+  }
+
  protected:
   void SetupProfile(const std::string& id,
                     uint32_t checksum,
@@ -69,19 +75,19 @@
   ProfileCompilationInfo::OfflineProfileMethodInfo GetOfflineProfileMethodInfo(
         const std::string& dex_location1, uint32_t dex_checksum1,
         const std::string& dex_location2, uint32_t dex_checksum2) {
-    ProfileCompilationInfo::OfflineProfileMethodInfo pmi;
+    ProfileCompilationInfo::OfflineProfileMethodInfo pmi(arena_.get());
     pmi.dex_references.emplace_back(dex_location1, dex_checksum1);
     pmi.dex_references.emplace_back(dex_location2, dex_checksum2);
 
     // Monomorphic
     for (uint16_t dex_pc = 0; dex_pc < 11; dex_pc++) {
-      ProfileCompilationInfo::DexPcData dex_pc_data;
+      ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.AddClass(0, dex::TypeIndex(0));
       pmi.inline_caches.Put(dex_pc, dex_pc_data);
     }
     // Polymorphic
     for (uint16_t dex_pc = 11; dex_pc < 22; dex_pc++) {
-      ProfileCompilationInfo::DexPcData dex_pc_data;
+      ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.AddClass(0, dex::TypeIndex(0));
       dex_pc_data.AddClass(1, dex::TypeIndex(1));
 
@@ -89,13 +95,13 @@
     }
     // Megamorphic
     for (uint16_t dex_pc = 22; dex_pc < 33; dex_pc++) {
-      ProfileCompilationInfo::DexPcData dex_pc_data;
+      ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.SetIsMegamorphic();
       pmi.inline_caches.Put(dex_pc, dex_pc_data);
     }
     // Missing types
     for (uint16_t dex_pc = 33; dex_pc < 44; dex_pc++) {
-      ProfileCompilationInfo::DexPcData dex_pc_data;
+      ProfileCompilationInfo::DexPcData dex_pc_data(arena_.get());
       dex_pc_data.SetIsMissingTypes();
       pmi.inline_caches.Put(dex_pc, dex_pc_data);
     }
@@ -247,13 +253,13 @@
                           bool is_megamorphic,
                           bool is_missing_types)
       REQUIRES_SHARED(Locks::mutator_lock_) {
-    ProfileCompilationInfo::OfflineProfileMethodInfo pmi;
-    ASSERT_TRUE(info.GetMethod(method->GetDexFile()->GetLocation(),
-                               method->GetDexFile()->GetLocationChecksum(),
-                               method->GetDexMethodIndex(),
-                               &pmi));
-    ASSERT_EQ(pmi.inline_caches.size(), 1u);
-    ProfileCompilationInfo::DexPcData dex_pc_data = pmi.inline_caches.begin()->second;
+    std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> pmi =
+        info.GetMethod(method->GetDexFile()->GetLocation(),
+                       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(dex_pc_data.is_megamorphic, is_megamorphic);
     ASSERT_EQ(dex_pc_data.is_missing_types, is_missing_types);
@@ -262,7 +268,7 @@
     for (mirror::Class* it : expected_clases) {
       for (const auto& class_ref : dex_pc_data.classes) {
         ProfileCompilationInfo::DexReference dex_ref =
-            pmi.dex_references[class_ref.dex_profile_index];
+            pmi->dex_references[class_ref.dex_profile_index];
         if (dex_ref.MatchesDex(&(it->GetDexFile())) &&
             class_ref.type_index == it->GetDexTypeIndex()) {
           found++;
@@ -272,6 +278,8 @@
 
     ASSERT_EQ(expected_clases.size(), found);
   }
+
+  std::unique_ptr<ArenaAllocator> arena_;
 };
 
 TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
@@ -541,11 +549,11 @@
   for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) {
     if (!method.IsCopied() && method.GetCodeItem() != nullptr) {
       ++method_count;
-      ProfileCompilationInfo::OfflineProfileMethodInfo pmi;
-      ASSERT_TRUE(info.GetMethod(method.GetDexFile()->GetLocation(),
-                                 method.GetDexFile()->GetLocationChecksum(),
-                                 method.GetDexMethodIndex(),
-                                 &pmi));
+      std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> pmi =
+          info.GetMethod(method.GetDexFile()->GetLocation(),
+                         method.GetDexFile()->GetLocationChecksum(),
+                         method.GetDexMethodIndex());
+      ASSERT_TRUE(pmi != nullptr);
     }
   }
   EXPECT_GT(method_count, 0u);
@@ -689,12 +697,12 @@
     // Verify that method noInlineCache has no inline caches in the profile.
     ArtMethod* no_inline_cache = GetVirtualMethod(class_loader, "LTestInline;", "noInlineCache");
     ASSERT_TRUE(no_inline_cache != nullptr);
-    ProfileCompilationInfo::OfflineProfileMethodInfo pmi_no_inline_cache;
-    ASSERT_TRUE(info.GetMethod(no_inline_cache->GetDexFile()->GetLocation(),
-                               no_inline_cache->GetDexFile()->GetLocationChecksum(),
-                               no_inline_cache->GetDexMethodIndex(),
-                               &pmi_no_inline_cache));
-    ASSERT_TRUE(pmi_no_inline_cache.inline_caches.empty());
+    std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> pmi_no_inline_cache =
+        info.GetMethod(no_inline_cache->GetDexFile()->GetLocation(),
+                       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());
   }
 }