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/profman.cc b/profman/profman.cc
index a99a0ea..963622d 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -139,6 +139,7 @@
 
 // Separators used when parsing human friendly representation of profiles.
 static const std::string kMethodSep = "->";
+static const std::string kMissingTypesMarker = "missing_types";
 static constexpr char kProfileParsingInlineChacheSep = '+';
 static constexpr char kProfileParsingTypeSep = ',';
 static constexpr char kProfileParsingFirstCharInSignature = '(';
@@ -624,8 +625,11 @@
 
   // Process a line defining a class or a method and its inline caches.
   // Upon success return true and add the class or the method info to profile.
-  // The format of the method line is:
+  // The possible line formats are:
+  // "LJustTheCass;".
   // "LTestInline;->inlinePolymorphic(LSuper;)I+LSubA;,LSubB;,LSubC;".
+  // "LTestInline;->inlineMissingTypes(LSuper;)I+missing_types".
+  // "LTestInline;->inlineNoInlineCaches(LSuper;)I".
   // The method and classes are searched only in the given dex files.
   bool ProcessLine(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
                    const std::string& line,
@@ -664,10 +668,14 @@
     std::vector<std::string> inline_cache_elems;
 
     std::vector<std::string> method_elems;
+    bool is_missing_types = false;
     Split(method_str, kProfileParsingInlineChacheSep, &method_elems);
     if (method_elems.size() == 2) {
       method_spec = method_elems[0];
-      Split(method_elems[1], kProfileParsingTypeSep, &inline_cache_elems);
+      is_missing_types = method_elems[1] == kMissingTypesMarker;
+      if (!is_missing_types) {
+        Split(method_elems[1], kProfileParsingTypeSep, &inline_cache_elems);
+      }
     } else if (method_elems.size() == 1) {
       method_spec = method_elems[0];
     } else {
@@ -689,7 +697,7 @@
       }
     }
     std::vector<ProfileMethodInfo::ProfileInlineCache> inline_caches;
-    inline_caches.emplace_back(dex_pc, classes);
+    inline_caches.emplace_back(dex_pc, is_missing_types, classes);
     std::vector<ProfileMethodInfo> pmi;
     pmi.emplace_back(class_ref.dex_file, method_index, inline_caches);