OSDN Git Service

Fix profile merges of megamorphic inline caches.
authorCalin Juravle <calin@google.com>
Wed, 22 Feb 2017 03:00:33 +0000 (19:00 -0800)
committerCalin Juravle <calin@google.com>
Wed, 22 Feb 2017 03:14:38 +0000 (19:14 -0800)
Test: m test-art-host-gtest-profile_compiltion_info_test
Bug: 35644850
Change-Id: Ib213715e263869c3aa6d4f81f0b7fe17f13b84c4

runtime/jit/profile_compilation_info.cc
runtime/jit/profile_compilation_info_test.cc

index 5638ce1..627cc93 100644 (file)
@@ -823,9 +823,13 @@ bool ProfileCompilationInfo::MergeWith(const ProfileCompilationInfo& other) {
         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);
+          }
         }
       }
     }
index 93b47ac..332280a 100644 (file)
@@ -175,13 +175,13 @@ class ProfileCompilationInfoTest : public CommonRuntimeTest {
     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 @@ class ProfileCompilationInfoTest : public CommonRuntimeTest {
        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 @@ TEST_F(ProfileCompilationInfoTest, AddMoreDexFileThanLimit) {
       /*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