Rewrite profile file format.

The new format contains one mandatory section and several
optional sections. This allows extending the profile with
new sections that shall be ignored by old versions of ART.

We add an "extra descriptors" section to support class
references without a `dex::TypeId` in the referencing dex
file. Type indexes between the dex file's `NumTypeIds()`
and `DexFile::kDexNoIndex16` are used to index these extra
descriptors. This prepares for collecting array classes
which shall be tied to the element type's dex file even
when the array type is not needed by that dex file and has
been used only from another dex file. It also allows inline
caches to be self-contained, so we can remove the profile
index from data structures and serialized data.

The creation of the the binary profile from text files is
updated to correctly allow array types to be stored as the
profiled classes using the "extra descriptors". However,
the interface for filling in inline caches remains unchanged
for now, so we require a `TypeId` in one of the processed
dex files. The data collection by JIT has not been updated.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --speed-profile
Test: boots.
Test: atest BootImageProfileTest
Bug: 148067697
Change-Id: Idd5f709bdc0ab4a3c7480d69d1dfac72d6e818fc
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 9e1965d..1d9520d 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -666,58 +666,23 @@
   }
   DCHECK_LE(dex_pc_data.classes.size(), InlineCache::kIndividualCacheSize);
 
-  Thread* self = Thread::Current();
-  // We need to resolve the class relative to the containing dex file.
-  // So first, build a mapping from the index of dex file in the profile to
-  // its dex cache. This will avoid repeating the lookup when walking over
-  // the inline cache types.
-  ScopedArenaAllocator allocator(graph_->GetArenaStack());
-  ScopedArenaVector<ObjPtr<mirror::DexCache>> dex_profile_index_to_dex_cache(
-        pci->GetNumberOfDexFiles(), nullptr, allocator.Adapter(kArenaAllocMisc));
-  const std::vector<const DexFile*>& dex_files =
-      codegen_->GetCompilerOptions().GetDexFilesForOatFile();
-  for (const ProfileCompilationInfo::ClassReference& class_ref : dex_pc_data.classes) {
-    if (dex_profile_index_to_dex_cache[class_ref.dex_profile_index] == nullptr) {
-      ProfileCompilationInfo::ProfileIndexType profile_index = class_ref.dex_profile_index;
-      const DexFile* dex_file = pci->FindDexFileForProfileIndex(profile_index, dex_files);
-      if (dex_file == nullptr) {
-        VLOG(compiler) << "Could not find profiled dex file: "
-            << pci->DumpDexReference(profile_index);
-        return kInlineCacheMissingTypes;
-      }
-      dex_profile_index_to_dex_cache[class_ref.dex_profile_index] =
-          caller_compilation_unit_.GetClassLinker()->FindDexCache(self, *dex_file);
-      DCHECK(dex_profile_index_to_dex_cache[class_ref.dex_profile_index] != nullptr);
-    }
-  }
-
-  // Walk over the classes and resolve them. If we cannot find a type we return
-  // kInlineCacheMissingTypes.
-  for (const ProfileCompilationInfo::ClassReference& class_ref : dex_pc_data.classes) {
-    ObjPtr<mirror::DexCache> dex_cache =
-        dex_profile_index_to_dex_cache[class_ref.dex_profile_index];
-    DCHECK(dex_cache != nullptr);
-
-    if (!dex_cache->GetDexFile()->IsTypeIndexValid(class_ref.type_index)) {
-      VLOG(compiler) << "Profile data corrupt: type index " << class_ref.type_index
-            << "is invalid in location" << dex_cache->GetDexFile()->GetLocation();
-      return kInlineCacheNoData;
-    }
-    ObjPtr<mirror::Class> clazz = caller_compilation_unit_.GetClassLinker()->LookupResolvedType(
-          class_ref.type_index,
-          dex_cache,
-          caller_compilation_unit_.GetClassLoader().Get());
-    if (clazz != nullptr) {
-      DCHECK_NE(classes->RemainingSlots(), 0u);
-      classes->NewHandle(clazz);
-    } else {
-      VLOG(compiler) << "Could not resolve class from inline cache in AOT mode "
+  // Walk over the class descriptors and look up the actual classes.
+  // If we cannot find a type we return kInlineCacheMissingTypes.
+  ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
+  for (const dex::TypeIndex& type_index : dex_pc_data.classes) {
+    const DexFile* dex_file = caller_compilation_unit_.GetDexFile();
+    const char* descriptor = pci->GetTypeDescriptor(dex_file, type_index);
+    ObjPtr<mirror::ClassLoader> class_loader = caller_compilation_unit_.GetClassLoader().Get();
+    ObjPtr<mirror::Class> clazz = class_linker->LookupResolvedType(descriptor, class_loader);
+    if (clazz == nullptr) {
+      VLOG(compiler) << "Could not find class from inline cache in AOT mode "
           << invoke_instruction->GetMethodReference().PrettyMethod()
           << " : "
-          << caller_compilation_unit_
-              .GetDexFile()->StringByTypeIdx(class_ref.type_index);
+          << descriptor;
       return kInlineCacheMissingTypes;
     }
+    DCHECK_NE(classes->RemainingSlots(), 0u);
+    classes->NewHandle(clazz);
   }
 
   return GetInlineCacheType(*classes);