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/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index d81dedc..92d9c1d 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -33,6 +33,7 @@
 
 namespace mirror {
 
+class MethodType;
 class String;
 
 template <typename T> struct PACKED(8) DexCachePair {
@@ -92,6 +93,9 @@
 using StringDexCachePair = DexCachePair<mirror::String>;
 using StringDexCacheType = std::atomic<StringDexCachePair>;
 
+using MethodTypeDexCachePair = DexCachePair<mirror::MethodType>;
+using MethodTypeDexCacheType = std::atomic<MethodTypeDexCachePair>;
+
 // C++ mirror of java.lang.DexCache.
 class MANAGED DexCache FINAL : public Object {
  public:
@@ -103,10 +107,20 @@
   static_assert(IsPowerOfTwo(kDexCacheStringCacheSize),
                 "String dex cache size is not a power of 2.");
 
+  // Size of method type dex cache. Needs to be a power of 2 for entrypoint assumptions
+  // to hold.
+  static constexpr size_t kDexCacheMethodTypeCacheSize = 1024;
+  static_assert(IsPowerOfTwo(kDexCacheMethodTypeCacheSize),
+                "MethodType dex cache size is not a power of 2.");
+
   static constexpr size_t StaticStringSize() {
     return kDexCacheStringCacheSize;
   }
 
+  static constexpr size_t StaticMethodTypeSize() {
+    return kDexCacheMethodTypeCacheSize;
+  }
+
   // Size of an instance of java.lang.DexCache not including referenced values.
   static constexpr uint32_t InstanceSize() {
     return sizeof(DexCache);
@@ -122,6 +136,8 @@
             uint32_t num_resolved_methods,
             ArtField** resolved_fields,
             uint32_t num_resolved_fields,
+            MethodTypeDexCacheType* resolved_methodtypes,
+            uint32_t num_resolved_methodtypes,
             PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_);
 
   void Fixup(ArtMethod* trampoline, PointerSize pointer_size)
@@ -159,6 +175,10 @@
     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
   }
 
+  static MemberOffset ResolvedMethodTypesOffset() {
+    return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_method_types_);
+  }
+
   static MemberOffset NumStringsOffset() {
     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
   }
@@ -175,6 +195,10 @@
     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
   }
 
+  static MemberOffset NumResolvedMethodTypesOffset() {
+    return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_);
+  }
+
   mirror::String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE
       REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -205,6 +229,10 @@
   ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, PointerSize ptr_size)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  MethodType* GetResolvedMethodType(uint32_t proto_idx) REQUIRES_SHARED(Locks::mutator_lock_);
+
+  void SetResolvedMethodType(uint32_t proto_idx, MethodType* resolved) REQUIRES_SHARED(Locks::mutator_lock_);
+
   StringDexCacheType* GetStrings() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetFieldPtr64<StringDexCacheType*>(StringsOffset());
   }
@@ -243,6 +271,17 @@
     SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
   }
 
+  MethodTypeDexCacheType* GetResolvedMethodTypes()
+      ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
+    return GetFieldPtr<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset());
+  }
+
+  void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types)
+      ALWAYS_INLINE
+      REQUIRES_SHARED(Locks::mutator_lock_) {
+    SetFieldPtr<false>(ResolvedMethodTypesOffset(), resolved_method_types);
+  }
+
   size_t NumStrings() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetField32(NumStringsOffset());
   }
@@ -259,6 +298,10 @@
     return GetField32(NumResolvedFieldsOffset());
   }
 
+  size_t NumResolvedMethodTypes() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return GetField32(NumResolvedMethodTypesOffset());
+  }
+
   const DexFile* GetDexFile() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
   }
@@ -290,16 +333,20 @@
 
   HeapReference<Object> dex_;
   HeapReference<String> location_;
-  uint64_t dex_file_;           // const DexFile*
-  uint64_t resolved_fields_;    // ArtField*, array with num_resolved_fields_ elements.
-  uint64_t resolved_methods_;   // ArtMethod*, array with num_resolved_methods_ elements.
-  uint64_t resolved_types_;     // GcRoot<Class>*, array with num_resolved_types_ elements.
-  uint64_t strings_;            // std::atomic<StringDexCachePair>*,
-                                // array with num_strings_ elements.
-  uint32_t num_resolved_fields_;    // Number of elements in the resolved_fields_ array.
-  uint32_t num_resolved_methods_;   // Number of elements in the resolved_methods_ array.
-  uint32_t num_resolved_types_;     // Number of elements in the resolved_types_ array.
-  uint32_t num_strings_;            // Number of elements in the strings_ array.
+  uint64_t dex_file_;               // const DexFile*
+  uint64_t resolved_fields_;        // ArtField*, array with num_resolved_fields_ elements.
+  uint64_t resolved_method_types_;  // std::atomic<MethodTypeDexCachePair>* array with
+                                    // num_resolved_method_types_ elements.
+  uint64_t resolved_methods_;       // ArtMethod*, array with num_resolved_methods_ elements.
+  uint64_t resolved_types_;         // GcRoot<Class>*, array with num_resolved_types_ elements.
+  uint64_t strings_;                // std::atomic<StringDexCachePair>*, array with num_strings_
+                                    // elements.
+
+  uint32_t num_resolved_fields_;        // Number of elements in the resolved_fields_ array.
+  uint32_t num_resolved_method_types_;  // Number of elements in the resolved_method_types_ array.
+  uint32_t num_resolved_methods_;       // Number of elements in the resolved_methods_ array.
+  uint32_t num_resolved_types_;         // Number of elements in the resolved_types_ array.
+  uint32_t num_strings_;                // Number of elements in the strings_ array.
 
   friend struct art::DexCacheOffsets;  // for verifying offset information
   friend class Object;  // For VisitReferences