Fix profile merges of megamorphic inline caches.
Test: m test-art-host-gtest-profile_compiltion_info_test
Bug: 35644850
Change-Id: Ib213715e263869c3aa6d4f81f0b7fe17f13b84c4
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 5638ce1..627cc93 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -823,9 +823,13 @@
uint16_t other_dex_pc = other_ic_it.first;
const ClassSet& other_class_set = other_ic_it.second.classes;
auto class_set = method_it->second.FindOrAdd(other_dex_pc);
- for (const auto& class_it : other_class_set) {
- class_set->second.AddClass(dex_profile_index_remap.Get(
- class_it.dex_profile_index), class_it.type_index);
+ if (other_ic_it.second.is_megamorphic) {
+ class_set->second.SetMegamorphic();
+ } else {
+ for (const auto& class_it : other_class_set) {
+ class_set->second.AddClass(dex_profile_index_remap.Get(
+ class_it.dex_profile_index), class_it.type_index);
+ }
}
}
}
diff --git a/runtime/jit/profile_compilation_info_test.cc b/runtime/jit/profile_compilation_info_test.cc
index 93b47ac..332280a 100644
--- a/runtime/jit/profile_compilation_info_test.cc
+++ b/runtime/jit/profile_compilation_info_test.cc
@@ -175,13 +175,13 @@
pmi.dex_references.emplace_back("dex_location3", /* checksum */ 3);
// Monomorphic
- for (uint16_t dex_pc = 0; dex_pc < 1; dex_pc++) {
+ for (uint16_t dex_pc = 0; dex_pc < 10; dex_pc++) {
ProfileCompilationInfo::DexPcData dex_pc_data;
dex_pc_data.AddClass(0, dex::TypeIndex(0));
pmi.inline_caches.Put(dex_pc, dex_pc_data);
}
// Polymorphic
- for (uint16_t dex_pc = 1; dex_pc < 2; dex_pc++) {
+ for (uint16_t dex_pc = 10; dex_pc < 20; dex_pc++) {
ProfileCompilationInfo::DexPcData dex_pc_data;
dex_pc_data.AddClass(0, dex::TypeIndex(0));
dex_pc_data.AddClass(1, dex::TypeIndex(1));
@@ -190,7 +190,7 @@
pmi.inline_caches.Put(dex_pc, dex_pc_data);
}
// Megamorphic
- for (uint16_t dex_pc = 2; dex_pc < 3; dex_pc++) {
+ for (uint16_t dex_pc = 20; dex_pc < 30; dex_pc++) {
ProfileCompilationInfo::DexPcData dex_pc_data;
dex_pc_data.is_megamorphic = true;
pmi.inline_caches.Put(dex_pc, dex_pc_data);
@@ -657,4 +657,33 @@
/*dex_location*/ "256", /* checksum */ 1, /* method_idx */ 0, &info));
}
+TEST_F(ProfileCompilationInfoTest, MegamorphicInlineCachesMerge) {
+ // Create a megamorphic inline cache.
+ ProfileCompilationInfo::OfflineProfileMethodInfo pmi;
+ pmi.dex_references.emplace_back("dex_location1", /* checksum */ 1);
+ ProfileCompilationInfo::DexPcData dex_pc_data;
+ dex_pc_data.is_megamorphic = true;
+ pmi.inline_caches.Put(/*dex_pc*/ 0, dex_pc_data);
+
+ ProfileCompilationInfo info_megamorphic;
+ ASSERT_TRUE(AddMethod("dex_location1",
+ /*checksum*/ 1,
+ /*method_idx*/ 0,
+ pmi,
+ &info_megamorphic));
+
+ // Create a profile with no inline caches (for the same method).
+ ProfileCompilationInfo info_no_inline_cache;
+ ASSERT_TRUE(AddMethod("dex_location1",
+ /*checksum*/ 1,
+ /*method_idx*/ 0,
+ &info_no_inline_cache));
+
+ // Merge the megamorphic cache into the empty one.
+ ASSERT_TRUE(info_no_inline_cache.MergeWith(info_megamorphic));
+ ScratchFile profile;
+ // Saving profile should work without crashing (b/35644850).
+ ASSERT_TRUE(info_no_inline_cache.Save(GetFd(profile)));
+}
+
} // namespace art