class_linker: Add support for resolving method types.

- Add a new fixed size dex cache array for resolved method types.
  The size of this array is set to 1024.
- Also introduces a new runtime flag that controls this feature.

Test: make test-art-host
Bug: 30550796

Change-Id: I147b33398d71ee21f2e91b418d3700d4630801ff
diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h
index a85d033..5ccd446 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -38,8 +38,10 @@
           RoundUp(methods_offset_ + MethodsSize(header.method_ids_size_), StringsAlignment())),
       fields_offset_(
           RoundUp(strings_offset_ + StringsSize(header.string_ids_size_), FieldsAlignment())),
+      method_types_offset_(
+          RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), Alignment())),
       size_(
-          RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), Alignment())) {
+          RoundUp(method_types_offset_ + MethodTypesSize(header.proto_ids_size_), Alignment())) {
 }
 
 inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, const DexFile* dex_file)
@@ -118,6 +120,27 @@
   return static_cast<size_t>(pointer_size_);
 }
 
+inline size_t DexCacheArraysLayout::MethodTypeOffset(uint32_t proto_idx) const {
+  return strings_offset_
+      + ElementOffset(PointerSize::k64,
+                      proto_idx % mirror::DexCache::kDexCacheMethodTypeCacheSize);
+}
+
+inline size_t DexCacheArraysLayout::MethodTypesSize(size_t num_elements) const {
+  size_t cache_size = mirror::DexCache::kDexCacheMethodTypeCacheSize;
+  if (num_elements < cache_size) {
+    cache_size = num_elements;
+  }
+
+  return ArraySize(PointerSize::k64, cache_size);
+}
+
+inline size_t DexCacheArraysLayout::MethodTypesAlignment() const {
+  static_assert(alignof(mirror::MethodTypeDexCacheType) == 8,
+                "alignof(MethodTypeDexCacheType) != 8");
+  return alignof(mirror::MethodTypeDexCacheType);
+}
+
 inline size_t DexCacheArraysLayout::ElementOffset(PointerSize element_size, uint32_t idx) {
   return static_cast<size_t>(element_size) * idx;
 }