Encode inline caches with missing types in the profile

Not all runtime types can be encoded in the profile. For example if the
receiver type is in a dex file which is not tracked for profiling its
type cannot be encoded.

Previously we would just skip over these types but that can lead to
encode a polymorphic inline cache when in fact it should be megamorphic.

With this CL, inline caches for which types are missing are marked in
the profile with a special bit, kIsMissingTypesEncoding.

Also, extend profman to understand text lines which specify an inline
cache with missing types.

Test: test-art-host

Bug: 35927981
Bug: 32434870
Change-Id: I34528a39c227f3133771fd4454701c1ddc234f40
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 5a758ae..52f3b52 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -182,7 +182,8 @@
   void AssertInlineCaches(ArtMethod* method,
                           const std::set<mirror::Class*>& expected_clases,
                           const ProfileCompilationInfo& info,
-                          bool megamorphic)
+                          bool is_megamorphic,
+                          bool is_missing_types)
       REQUIRES_SHARED(Locks::mutator_lock_) {
     ProfileCompilationInfo::OfflineProfileMethodInfo pmi;
     ASSERT_TRUE(info.GetMethod(method->GetDexFile()->GetLocation(),
@@ -192,7 +193,8 @@
     ASSERT_EQ(pmi.inline_caches.size(), 1u);
     ProfileCompilationInfo::DexPcData dex_pc_data = pmi.inline_caches.begin()->second;
 
-    ASSERT_EQ(dex_pc_data.is_megamorphic, megamorphic);
+    ASSERT_EQ(dex_pc_data.is_megamorphic, is_megamorphic);
+    ASSERT_EQ(dex_pc_data.is_missing_types, is_missing_types);
     ASSERT_EQ(expected_clases.size(), dex_pc_data.classes.size());
     size_t found = 0;
     for (mirror::Class* it : expected_clases) {
@@ -482,6 +484,7 @@
     "LTestInline;->inlineMonomorphic(LSuper;)I+LSubA;",
     "LTestInline;->inlinePolymorphic(LSuper;)I+LSubA;,LSubB;,LSubC;",
     "LTestInline;->inlineMegamorphic(LSuper;)I+LSubA;,LSubB;,LSubC;,LSubD;,LSubE;",
+    "LTestInline;->inlineMissingTypes(LSuper;)I+missing_types",
     "LTestInline;->noInlineCache(LSuper;)I"
   };
   std::string input_file_contents;
@@ -521,7 +524,11 @@
     ASSERT_TRUE(inline_monomorphic != nullptr);
     std::set<mirror::Class*> expected_monomorphic;
     expected_monomorphic.insert(sub_a);
-    AssertInlineCaches(inline_monomorphic, expected_monomorphic, info, /*megamorphic*/ false);
+    AssertInlineCaches(inline_monomorphic,
+                       expected_monomorphic,
+                       info,
+                       /*megamorphic*/false,
+                       /*missing_types*/false);
   }
 
   {
@@ -534,7 +541,11 @@
     expected_polymorphic.insert(sub_a);
     expected_polymorphic.insert(sub_b);
     expected_polymorphic.insert(sub_c);
-    AssertInlineCaches(inline_polymorhic, expected_polymorphic, info, /*megamorphic*/ false);
+    AssertInlineCaches(inline_polymorhic,
+                       expected_polymorphic,
+                       info,
+                       /*megamorphic*/false,
+                       /*missing_types*/false);
   }
 
   {
@@ -544,7 +555,25 @@
                                                      "inlineMegamorphic");
     ASSERT_TRUE(inline_megamorphic != nullptr);
     std::set<mirror::Class*> expected_megamorphic;
-    AssertInlineCaches(inline_megamorphic, expected_megamorphic, info, /*megamorphic*/ true);
+    AssertInlineCaches(inline_megamorphic,
+                       expected_megamorphic,
+                       info,
+                       /*megamorphic*/true,
+                       /*missing_types*/false);
+  }
+
+  {
+    // Verify that method inlineMegamorphic has the expected inline caches and nothing else.
+    ArtMethod* inline_missing_types = GetVirtualMethod(class_loader,
+                                                       "LTestInline;",
+                                                       "inlineMissingTypes");
+    ASSERT_TRUE(inline_missing_types != nullptr);
+    std::set<mirror::Class*> expected_missing_Types;
+    AssertInlineCaches(inline_missing_types,
+                       expected_missing_Types,
+                       info,
+                       /*megamorphic*/false,
+                       /*missing_types*/true);
   }
 
   {