• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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_VAR_HANDLE_H_
18 #define ART_RUNTIME_MIRROR_VAR_HANDLE_H_
19 
20 #include "handle.h"
21 #include "interpreter/shadow_frame.h"
22 #include "jvalue.h"
23 #include "object.h"
24 
25 namespace art {
26 
27 template<class T> class Handle;
28 class InstructionOperands;
29 template<class T> class ObjPtr;
30 
31 enum class Intrinsics;
32 
33 struct VarHandleOffsets;
34 struct FieldVarHandleOffsets;
35 struct StaticFieldVarHandleOffsets;
36 struct ArrayElementVarHandleOffsets;
37 struct ByteArrayViewVarHandleOffsets;
38 struct ByteBufferViewVarHandleOffsets;
39 
40 class ReflectiveValueVisitor;
41 class ShadowFrameGetter;
42 
43 namespace mirror {
44 
45 class MethodType;
46 class VarHandleTest;
47 
48 // C++ mirror of java.lang.invoke.VarHandle
49 class MANAGED VarHandle : public Object {
50  public:
51   MIRROR_CLASS("Ljava/lang/invoke/VarHandle;");
52 
53   // The maximum number of parameters a VarHandle accessor method can
54   // take. The Worst case is equivalent to a compare-and-swap
55   // operation on an array element which requires four parameters
56   // (array, index, old, new).
57   static constexpr int kMaxAccessorParameters = 4;
58 
59   // The maximum number of VarType parameters a VarHandle accessor
60   // method can take.
61   static constexpr size_t kMaxVarTypeParameters = 2;
62 
63   // The minimum number of CoordinateType parameters a VarHandle acessor method may take.
64   static constexpr size_t kMinCoordinateTypes = 0;
65 
66   // The maximum number of CoordinateType parameters a VarHandle acessor method may take.
67   static constexpr size_t kMaxCoordinateTypes = 2;
68 
69   // Enumeration of the possible access modes. This mirrors the enum
70   // in java.lang.invoke.VarHandle.
71   enum class AccessMode : uint32_t {
72     kGet,
73     kSet,
74     kGetVolatile,
75     kSetVolatile,
76     kGetAcquire,
77     kSetRelease,
78     kGetOpaque,
79     kSetOpaque,
80     kCompareAndSet,
81     kCompareAndExchange,
82     kCompareAndExchangeAcquire,
83     kCompareAndExchangeRelease,
84     kWeakCompareAndSetPlain,
85     kWeakCompareAndSet,
86     kWeakCompareAndSetAcquire,
87     kWeakCompareAndSetRelease,
88     kGetAndSet,
89     kGetAndSetAcquire,
90     kGetAndSetRelease,
91     kGetAndAdd,
92     kGetAndAddAcquire,
93     kGetAndAddRelease,
94     kGetAndBitwiseOr,
95     kGetAndBitwiseOrRelease,
96     kGetAndBitwiseOrAcquire,
97     kGetAndBitwiseAnd,
98     kGetAndBitwiseAndRelease,
99     kGetAndBitwiseAndAcquire,
100     kGetAndBitwiseXor,
101     kGetAndBitwiseXorRelease,
102     kGetAndBitwiseXorAcquire,
103     kLast = kGetAndBitwiseXorAcquire,
104   };
105   constexpr static size_t kNumberOfAccessModes = static_cast<size_t>(AccessMode::kLast) + 1u;
106 
107   // Enumeration for describing the parameter and return types of an AccessMode.
108   enum class AccessModeTemplate : uint32_t {
109     kGet,                 // T Op(C0..CN)
110     kSet,                 // void Op(C0..CN, T)
111     kCompareAndSet,       // boolean Op(C0..CN, T, T)
112     kCompareAndExchange,  // T Op(C0..CN, T, T)
113     kGetAndUpdate,        // T Op(C0..CN, T)
114   };
115 
116   // Returns true if the AccessMode specified is a supported operation.
IsAccessModeSupported(AccessMode accessMode)117   bool IsAccessModeSupported(AccessMode accessMode) REQUIRES_SHARED(Locks::mutator_lock_) {
118     return (GetAccessModesBitMask() & (1u << static_cast<uint32_t>(accessMode))) != 0;
119   }
120 
121   enum MatchKind : uint8_t {
122     kNone,
123     kWithConversions,
124     kExact
125   };
126 
127   // Returns match information on the compatability between the exact method type for
128   // 'access_mode' and the provided 'method_type'.
129   MatchKind GetMethodTypeMatchForAccessMode(AccessMode access_mode, ObjPtr<MethodType> method_type)
130         REQUIRES_SHARED(Locks::mutator_lock_);
131 
132   // Allocates and returns the MethodType associated with the
133   // AccessMode. No check is made for whether the AccessMode is a
134   // supported operation so the MethodType can be used when raising a
135   // WrongMethodTypeException exception.
136   ObjPtr<MethodType> GetMethodTypeForAccessMode(Thread* self, AccessMode accessMode)
137       REQUIRES_SHARED(Locks::mutator_lock_);
138 
139   // Returns a string representing the descriptor of the MethodType associated with
140   // this AccessMode.
141   std::string PrettyDescriptorForAccessMode(AccessMode access_mode)
142       REQUIRES_SHARED(Locks::mutator_lock_);
143 
144   bool Access(AccessMode access_mode,
145               ShadowFrame* shadow_frame,
146               const InstructionOperands* const operands,
147               JValue* result)
148       REQUIRES_SHARED(Locks::mutator_lock_);
149 
150   // Gets the variable type that is operated on by this VarHandle instance.
151   ObjPtr<Class> GetVarType() REQUIRES_SHARED(Locks::mutator_lock_);
152 
153   // Gets the type of the object that this VarHandle operates on, null for StaticFieldVarHandle.
154   ObjPtr<Class> GetCoordinateType0() REQUIRES_SHARED(Locks::mutator_lock_);
155 
156   // Gets the return type descriptor for a named accessor method,
157   // nullptr if accessor_method is not supported.
158   static const char* GetReturnTypeDescriptor(const char* accessor_method);
159 
160   // Returns the AccessMode corresponding to a VarHandle accessor intrinsic.
161   static AccessMode GetAccessModeByIntrinsic(Intrinsics ordinal);
162 
163   // Returns true and sets access_mode if method_name corresponds to a
164   // VarHandle access method, such as "setOpaque". Returns false otherwise.
165   static bool GetAccessModeByMethodName(const char* method_name, AccessMode* access_mode);
166 
167   // Returns the AccessModeTemplate for a given mode.
168   static AccessModeTemplate GetAccessModeTemplate(AccessMode access_mode);
169 
170   // Returns the AccessModeTemplate corresponding to a VarHandle accessor intrinsic.
171   static AccessModeTemplate GetAccessModeTemplateByIntrinsic(Intrinsics ordinal);
172 
173   // Returns the number of VarType parameters for an access mode template.
174   static int32_t GetNumberOfVarTypeParameters(AccessModeTemplate access_mode_template);
175 
VarTypeOffset()176   static MemberOffset VarTypeOffset() {
177     return MemberOffset(OFFSETOF_MEMBER(VarHandle, var_type_));
178   }
179 
CoordinateType0Offset()180   static MemberOffset CoordinateType0Offset() {
181     return MemberOffset(OFFSETOF_MEMBER(VarHandle, coordinate_type0_));
182   }
183 
CoordinateType1Offset()184   static MemberOffset CoordinateType1Offset() {
185     return MemberOffset(OFFSETOF_MEMBER(VarHandle, coordinate_type1_));
186   }
187 
AccessModesBitMaskOffset()188   static MemberOffset AccessModesBitMaskOffset() {
189     return MemberOffset(OFFSETOF_MEMBER(VarHandle, access_modes_bit_mask_));
190   }
191 
192  private:
193   ObjPtr<Class> GetCoordinateType1() REQUIRES_SHARED(Locks::mutator_lock_);
194   int32_t GetAccessModesBitMask() REQUIRES_SHARED(Locks::mutator_lock_);
195 
196   static ObjPtr<MethodType> GetMethodTypeForAccessMode(Thread* self,
197                                                        ObjPtr<VarHandle> var_handle,
198                                                        AccessMode access_mode)
199       REQUIRES_SHARED(Locks::mutator_lock_);
200 
201   HeapReference<mirror::Class> coordinate_type0_;
202   HeapReference<mirror::Class> coordinate_type1_;
203   HeapReference<mirror::Class> var_type_;
204   int32_t access_modes_bit_mask_;
205 
206   friend class VarHandleTest;  // for testing purposes
207   friend struct art::VarHandleOffsets;  // for verifying offset information
208   DISALLOW_IMPLICIT_CONSTRUCTORS(VarHandle);
209 };
210 
211 // Represents a VarHandle to a static or instance field.
212 // The corresponding managed class in libart java.lang.invoke.FieldVarHandle.
213 class MANAGED FieldVarHandle : public VarHandle {
214  public:
215   MIRROR_CLASS("Ljava/lang/invoke/FieldVarHandle;");
216 
217   bool Access(AccessMode access_mode,
218               ShadowFrame* shadow_frame,
219               const InstructionOperands* const operands,
220               JValue* result)
221       REQUIRES_SHARED(Locks::mutator_lock_);
222 
223   template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
GetArtField()224   ArtField* GetArtField() REQUIRES_SHARED(Locks::mutator_lock_) {
225     return reinterpret_cast64<ArtField*>(GetField64<kVerifyFlags>(ArtFieldOffset()));
226   }
227 
228   template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
SetArtField(ArtField * art_field)229   void SetArtField(ArtField* art_field) REQUIRES_SHARED(Locks::mutator_lock_) {
230     SetField64</*kTransactionActive*/ false,
231                /*kCheckTransaction=*/ true,
232                kVerifyFlags>(ArtFieldOffset(), reinterpret_cast64<uint64_t>(art_field));
233   }
234 
235   // Used for updating var-handles to obsolete fields.
236   void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
237 
ArtFieldOffset()238   static MemberOffset ArtFieldOffset() {
239     return MemberOffset(OFFSETOF_MEMBER(FieldVarHandle, art_field_));
240   }
241 
242  private:
243   // ArtField instance corresponding to variable for accessors.
244   int64_t art_field_;
245 
246   friend class VarHandleTest;  // for var_handle_test.
247   friend struct art::FieldVarHandleOffsets;  // for verifying offset information
248   DISALLOW_IMPLICIT_CONSTRUCTORS(FieldVarHandle);
249 };
250 
251 class MANAGED StaticFieldVarHandle : public FieldVarHandle {
252  public:
253   MIRROR_CLASS("Ljava/lang/invoke/StaticFieldVarHandle;");
254 
255   // Used for updating var-handles to obsolete fields.
256   void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
257 
DeclaringClassOffset()258   static MemberOffset DeclaringClassOffset() {
259     return MemberOffset(OFFSETOF_MEMBER(StaticFieldVarHandle, declaring_class_));
260   }
261 
262  private:
263   HeapReference<mirror::Class> declaring_class_;
264 
265   friend class VarHandleTest;  // for var_handle_test.
266   friend struct art::StaticFieldVarHandleOffsets;  // for verifying offset information
267   DISALLOW_IMPLICIT_CONSTRUCTORS(StaticFieldVarHandle);
268 };
269 
270 
271 // Represents a VarHandle providing accessors to an array.
272 // The corresponding managed class in libart java.lang.invoke.ArrayElementVarHandle.
273 class MANAGED ArrayElementVarHandle : public VarHandle {
274  public:
275   bool Access(AccessMode access_mode,
276               ShadowFrame* shadow_frame,
277               const InstructionOperands* const operands,
278               JValue* result) REQUIRES_SHARED(Locks::mutator_lock_);
279 
280  private:
281   static bool CheckArrayStore(AccessMode access_mode,
282                               ShadowFrameGetter getter,
283                               ObjPtr<ObjectArray<Object>> array)
284       REQUIRES_SHARED(Locks::mutator_lock_);
285 
286   friend class VarHandleTest;
287   DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayElementVarHandle);
288 };
289 
290 // Represents a VarHandle providing accessors to a view of a ByteArray.
291 // The corresponding managed class in libart java.lang.invoke.ByteArrayViewVarHandle.
292 class MANAGED ByteArrayViewVarHandle : public VarHandle {
293  public:
294   MIRROR_CLASS("Ljava/lang/invoke/ByteArrayViewVarHandle;");
295 
296   bool Access(AccessMode access_mode,
297               ShadowFrame* shadow_frame,
298               const InstructionOperands* const operands,
299               JValue* result)
300       REQUIRES_SHARED(Locks::mutator_lock_);
301 
302   bool GetNativeByteOrder() REQUIRES_SHARED(Locks::mutator_lock_);
303 
NativeByteOrderOffset()304   static MemberOffset NativeByteOrderOffset() {
305     return MemberOffset(OFFSETOF_MEMBER(ByteArrayViewVarHandle, native_byte_order_));
306   }
307 
308  private:
309   // Flag indicating that accessors should use native byte-ordering.
310   uint8_t native_byte_order_;
311 
312   friend class VarHandleTest;  // for var_handle_test.
313   friend struct art::ByteArrayViewVarHandleOffsets;  // for verifying offset information
314   DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArrayViewVarHandle);
315 };
316 
317 // Represents a VarHandle providing accessors to a view of a ByteBuffer
318 // The corresponding managed class in libart java.lang.invoke.ByteBufferViewVarHandle.
319 class MANAGED ByteBufferViewVarHandle : public VarHandle {
320  public:
321   MIRROR_CLASS("Ljava/lang/invoke/ByteBufferViewVarHandle;");
322 
323   bool Access(AccessMode access_mode,
324               ShadowFrame* shadow_frame,
325               const InstructionOperands* const operands,
326               JValue* result)
327       REQUIRES_SHARED(Locks::mutator_lock_);
328 
329   bool GetNativeByteOrder() REQUIRES_SHARED(Locks::mutator_lock_);
330 
331  private:
332   bool AccessHeapBuffer(AccessMode access_mode,
333                         ObjPtr<Object> byte_buffer,
334                         int buffer_offset,
335                         ObjPtr<ByteArray> heap_byte_array,
336                         ShadowFrameGetter* getter,
337                         JValue* result)
338       REQUIRES_SHARED(Locks::mutator_lock_);
339 
340   bool AccessFixedMemory(AccessMode access_mode,
341                          ObjPtr<Object> byte_buffer,
342                          int buffer_offset,
343                          ShadowFrameGetter* getter,
344                          JValue* result)
345       REQUIRES_SHARED(Locks::mutator_lock_);
346 
NativeByteOrderOffset()347   static MemberOffset NativeByteOrderOffset() {
348     return MemberOffset(OFFSETOF_MEMBER(ByteBufferViewVarHandle, native_byte_order_));
349   }
350 
351   // Flag indicating that accessors should use native byte-ordering.
352   uint8_t native_byte_order_;
353 
354   friend class VarHandleTest;  // for var_handle_test.
355   friend struct art::ByteBufferViewVarHandleOffsets;  // for verifying offset information
356   DISALLOW_IMPLICIT_CONSTRUCTORS(ByteBufferViewVarHandle);
357 };
358 
359 }  // namespace mirror
360 }  // namespace art
361 
362 #endif  // ART_RUNTIME_MIRROR_VAR_HANDLE_H_
363