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