1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_MIRROR_METHOD_TYPE_H_ 18 #define ART_RUNTIME_MIRROR_METHOD_TYPE_H_ 19 20 #include "base/macros.h" 21 #include "object_array.h" 22 #include "object.h" 23 #include "string.h" 24 25 namespace art HIDDEN { 26 27 struct MethodTypeOffsets; 28 class VariableSizedHandleScope; 29 30 namespace mirror { 31 32 // We use a wrapped `VariableSizedHandleScope` as a raw method type without allocating a managed 33 // object. It must contain the return type followed by argument types and no other handles. 34 // The data is filled by calling `SetRType()` followed by `AddPType()` for each argument. 35 class RawMethodType { 36 public: 37 explicit RawMethodType(VariableSizedHandleScope* hs); 38 39 bool IsValid() const; 40 41 void SetRType(ObjPtr<mirror::Class> rtype) REQUIRES_SHARED(Locks::mutator_lock_); 42 void AddPType(ObjPtr<mirror::Class> ptype) REQUIRES_SHARED(Locks::mutator_lock_); 43 44 int32_t GetNumberOfPTypes() const REQUIRES_SHARED(Locks::mutator_lock_); 45 ObjPtr<mirror::Class> GetPType(int32_t i) const REQUIRES_SHARED(Locks::mutator_lock_); 46 ObjPtr<mirror::Class> GetRType() const REQUIRES_SHARED(Locks::mutator_lock_); 47 Handle<mirror::Class> GetRTypeHandle() const REQUIRES_SHARED(Locks::mutator_lock_); 48 49 private: 50 VariableSizedHandleScope* hs_; 51 }; 52 53 // C++ mirror of java.lang.invoke.MethodType 54 class MANAGED MethodType : public Object { 55 public: 56 MIRROR_CLASS("Ljava/lang/invoke/MethodType;"); 57 58 EXPORT static ObjPtr<MethodType> Create(Thread* self, 59 Handle<Class> return_type, 60 Handle<ObjectArray<Class>> param_types) 61 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 62 63 // Create a `MethodType` from a `RawMethodType`. 64 static ObjPtr<MethodType> Create(Thread* self, RawMethodType method_type) 65 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 66 67 static ObjPtr<MethodType> CloneWithoutLeadingParameter(Thread* self, 68 ObjPtr<MethodType> method_type) 69 REQUIRES_SHARED(Locks::mutator_lock_); 70 71 // Collects trailing parameter types into an array. Assumes caller 72 // has checked trailing arguments are all of the same type. 73 static ObjPtr<MethodType> CollectTrailingArguments(Thread* self, 74 ObjPtr<MethodType> method_type, 75 ObjPtr<Class> collector_array_class, 76 int32_t start_index) 77 REQUIRES_SHARED(Locks::mutator_lock_); 78 79 ObjPtr<ObjectArray<Class>> GetPTypes() REQUIRES_SHARED(Locks::mutator_lock_); 80 81 int GetNumberOfPTypes() REQUIRES_SHARED(Locks::mutator_lock_); 82 83 // Number of virtual registers required to hold the parameters for 84 // this method type. 85 size_t NumberOfVRegs() REQUIRES_SHARED(Locks::mutator_lock_); 86 87 ObjPtr<Class> GetRType() REQUIRES_SHARED(Locks::mutator_lock_); 88 89 // Returns true iff. |this| is an exact match for method type |target|, i.e 90 // iff. they have the same return types and parameter types. 91 bool IsExactMatch(ObjPtr<MethodType> target) REQUIRES_SHARED(Locks::mutator_lock_); 92 93 // Returns true iff. |this| can be converted to match |target| method type, i.e 94 // iff. they have convertible return types and parameter types. 95 bool IsConvertible(ObjPtr<MethodType> target) REQUIRES_SHARED(Locks::mutator_lock_); 96 97 // Returns true iff. |this| can be converted to match |target| method type within the 98 // current frame of the current MethodType. This limits conversions to assignability check 99 // for references and between scalar 32-bit types. 100 bool IsInPlaceConvertible(ObjPtr<MethodType> target) REQUIRES_SHARED(Locks::mutator_lock_); 101 102 // Returns the pretty descriptor for this method type, suitable for display in 103 // exception messages and the like. 104 std::string PrettyDescriptor() REQUIRES_SHARED(Locks::mutator_lock_); 105 106 // The `PTypesType` is either `ObjPtr<>` or `Handle<>`. 107 template <typename PTypesType> 108 class PTypesAccessor { 109 public: 110 explicit PTypesAccessor(PTypesType p_types) REQUIRES_SHARED(Locks::mutator_lock_); 111 112 int32_t GetLength() const REQUIRES_SHARED(Locks::mutator_lock_); 113 ObjPtr<mirror::Class> Get(int32_t i) const REQUIRES_SHARED(Locks::mutator_lock_); 114 115 private: 116 static_assert(std::is_same_v<PTypesType, ObjPtr<ObjectArray<Class>>> || 117 std::is_same_v<PTypesType, Handle<ObjectArray<Class>>>); 118 119 const PTypesType p_types_; 120 }; 121 122 using ObjPtrPTypesAccessor = PTypesAccessor<ObjPtr<ObjectArray<Class>>>; 123 using HandlePTypesAccessor = PTypesAccessor<Handle<ObjectArray<Class>>>; 124 125 class RawPTypesAccessor { 126 public: 127 explicit RawPTypesAccessor(RawMethodType method_type); 128 129 int32_t GetLength() const REQUIRES_SHARED(Locks::mutator_lock_); 130 ObjPtr<mirror::Class> Get(int32_t i) const REQUIRES_SHARED(Locks::mutator_lock_); 131 132 private: 133 RawMethodType method_type_; 134 }; 135 136 template <typename HandleScopeType> 137 static HandlePTypesAccessor NewHandlePTypes(Handle<MethodType> method_type, HandleScopeType* hs) 138 REQUIRES_SHARED(Locks::mutator_lock_); 139 template <typename HandleScopeType> 140 static RawPTypesAccessor NewHandlePTypes(RawMethodType method_type, HandleScopeType* hs) 141 REQUIRES_SHARED(Locks::mutator_lock_); 142 143 static ObjPtrPTypesAccessor GetPTypes(ObjPtr<MethodType> method_type) 144 REQUIRES_SHARED(Locks::mutator_lock_); 145 static ObjPtrPTypesAccessor GetPTypes(Handle<MethodType> method_type) 146 REQUIRES_SHARED(Locks::mutator_lock_); 147 static RawPTypesAccessor GetPTypes(RawMethodType method_type) 148 REQUIRES_SHARED(Locks::mutator_lock_); 149 150 static ObjPtr<mirror::Class> GetRType(ObjPtr<MethodType> method_type) 151 REQUIRES_SHARED(Locks::mutator_lock_); 152 static ObjPtr<mirror::Class> GetRType(Handle<MethodType> method_type) 153 REQUIRES_SHARED(Locks::mutator_lock_); 154 static ObjPtr<mirror::Class> GetRType(RawMethodType method_type) 155 REQUIRES_SHARED(Locks::mutator_lock_); 156 157 static size_t NumberOfVRegs(ObjPtr<mirror::MethodType> method_type) 158 REQUIRES_SHARED(Locks::mutator_lock_); 159 static size_t NumberOfVRegs(Handle<mirror::MethodType> method_type) 160 REQUIRES_SHARED(Locks::mutator_lock_); 161 static size_t NumberOfVRegs(RawMethodType method_type) 162 REQUIRES_SHARED(Locks::mutator_lock_); 163 164 static std::string PrettyDescriptor(ObjPtr<MethodType> method_type) 165 REQUIRES_SHARED(Locks::mutator_lock_); 166 static std::string PrettyDescriptor(Handle<MethodType> method_type) 167 REQUIRES_SHARED(Locks::mutator_lock_); 168 static std::string PrettyDescriptor(RawMethodType method_type) 169 REQUIRES_SHARED(Locks::mutator_lock_); 170 171 private: FormOffset()172 static MemberOffset FormOffset() { 173 return MemberOffset(OFFSETOF_MEMBER(MethodType, form_)); 174 } 175 MethodDescriptorOffset()176 static MemberOffset MethodDescriptorOffset() { 177 return MemberOffset(OFFSETOF_MEMBER(MethodType, method_descriptor_)); 178 } 179 PTypesOffset()180 static MemberOffset PTypesOffset() { 181 return MemberOffset(OFFSETOF_MEMBER(MethodType, p_types_)); 182 } 183 RTypeOffset()184 static MemberOffset RTypeOffset() { 185 return MemberOffset(OFFSETOF_MEMBER(MethodType, r_type_)); 186 } 187 WrapAltOffset()188 static MemberOffset WrapAltOffset() { 189 return MemberOffset(OFFSETOF_MEMBER(MethodType, wrap_alt_)); 190 } 191 192 HeapReference<Object> form_; // Unused in the runtime 193 HeapReference<String> method_descriptor_; // Unused in the runtime 194 HeapReference<ObjectArray<Class>> p_types_; 195 HeapReference<Class> r_type_; 196 HeapReference<Object> wrap_alt_; // Unused in the runtime 197 198 friend struct art::MethodTypeOffsets; // for verifying offset information 199 DISALLOW_IMPLICIT_CONSTRUCTORS(MethodType); 200 }; 201 202 } // namespace mirror 203 } // namespace art 204 205 #endif // ART_RUNTIME_MIRROR_METHOD_TYPE_H_ 206