From cc3171ab3af35b4e4ad5671d7425aa8a6bfcc5f3 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Fri, 19 May 2017 16:47:53 -0700 Subject: 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 --- profman/profile_assistant_test.cc | 56 ++++++++++++++++++++++----------------- profman/profman.cc | 3 ++- 2 files changed, 34 insertions(+), 25 deletions(-) (limited to 'profman') diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc index 38254e2436..b8366323d6 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 @@ class ProfileAssistantTest : public CommonRuntimeTest { 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 @@ class ProfileAssistantTest : public CommonRuntimeTest { } // 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 @@ class ProfileAssistantTest : public CommonRuntimeTest { 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 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 @@ class ProfileAssistantTest : public CommonRuntimeTest { 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 @@ class ProfileAssistantTest : public CommonRuntimeTest { ASSERT_EQ(expected_clases.size(), found); } + + std::unique_ptr arena_; }; TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) { @@ -541,11 +549,11 @@ TEST_F(ProfileAssistantTest, TestProfileCreationGenerateMethods) { 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 pmi = + info.GetMethod(method.GetDexFile()->GetLocation(), + method.GetDexFile()->GetLocationChecksum(), + method.GetDexMethodIndex()); + ASSERT_TRUE(pmi != nullptr); } } EXPECT_GT(method_count, 0u); @@ -689,12 +697,12 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { // 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 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()); } } diff --git a/profman/profman.cc b/profman/profman.cc index 384e129150..26e7e46033 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -423,7 +423,8 @@ class ProfMan FINAL { } for (const std::unique_ptr& dex_file : *dex_files) { std::set class_types; - ProfileCompilationInfo::MethodMap methods; + ProfileCompilationInfo::MethodMap methods(std::less(), + profile_info.GetArena()->Adapter()); if (profile_info.GetClassesAndMethods(dex_file.get(), &class_types, &methods)) { for (const dex::TypeIndex& type_index : class_types) { const DexFile::TypeId& type_id = dex_file->GetTypeId(type_index); -- cgit v1.2.3