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 #include "var_handle.h"
18 
19 #include <string>
20 #include <vector>
21 
22 #include "art_field-inl.h"
23 #include "class-alloc-inl.h"
24 #include "class-inl.h"
25 #include "class_linker-inl.h"
26 #include "class_loader.h"
27 #include "class_root-inl.h"
28 #include "common_runtime_test.h"
29 #include "handle_scope-inl.h"
30 #include "jvalue-inl.h"
31 #include "method_type.h"
32 #include "object_array-alloc-inl.h"
33 #include "object_array-inl.h"
34 #include "reflection.h"
35 #include "scoped_thread_state_change-inl.h"
36 
37 namespace art HIDDEN {
38 namespace mirror {
39 
40 // Tests for mirror::VarHandle and it's descendents.
41 class VarHandleTest : public CommonRuntimeTest {
42  public:
VarHandleTest()43   VarHandleTest() {
44     use_boot_image_ = true;  // Make the Runtime creation cheaper.
45   }
46 
CreateFieldVarHandle(Thread * const self,ArtField * art_field,int32_t access_modes_bit_mask)47   static ObjPtr<FieldVarHandle> CreateFieldVarHandle(Thread* const self,
48                                                      ArtField* art_field,
49                                                      int32_t access_modes_bit_mask)
50       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
51     StackHandleScope<4> hs(self);
52     Handle<FieldVarHandle> fvh = hs.NewHandle(
53         ObjPtr<FieldVarHandle>::DownCast(GetClassRoot<FieldVarHandle>()->AllocObject(self)));
54     Handle<Class> var_type = hs.NewHandle(art_field->ResolveType());
55 
56     if (art_field->IsStatic()) {
57       InitializeVarHandle(fvh.Get(), var_type, access_modes_bit_mask);
58     } else {
59       Handle<Class> declaring_type = hs.NewHandle(art_field->GetDeclaringClass());
60       InitializeVarHandle(fvh.Get(),
61                           var_type,
62                           declaring_type,
63                           access_modes_bit_mask);
64     }
65     uintptr_t opaque_field = reinterpret_cast<uintptr_t>(art_field);
66     fvh->SetField64<false>(FieldVarHandle::ArtFieldOffset(), opaque_field);
67     return fvh.Get();
68   }
69 
CreateArrayElementVarHandle(Thread * const self,Handle<Class> array_class,int32_t access_modes_bit_mask)70   static ObjPtr<ArrayElementVarHandle> CreateArrayElementVarHandle(Thread* const self,
71                                                                    Handle<Class> array_class,
72                                                                    int32_t access_modes_bit_mask)
73       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
74     StackHandleScope<3> hs(self);
75     Handle<ArrayElementVarHandle> vh = hs.NewHandle(
76         ObjPtr<ArrayElementVarHandle>::DownCast(
77             GetClassRoot<ArrayElementVarHandle>()->AllocObject(self)));
78 
79     // Initialize super class fields
80     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
81     Handle<Class> var_type = hs.NewHandle(array_class->GetComponentType());
82     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
83     InitializeVarHandle(vh.Get(), var_type, array_class, index_type, access_modes_bit_mask);
84     return vh.Get();
85   }
86 
CreateByteArrayViewVarHandle(Thread * const self,Handle<Class> view_array_class,bool native_byte_order,int32_t access_modes_bit_mask)87   static ObjPtr<ByteArrayViewVarHandle> CreateByteArrayViewVarHandle(
88       Thread* const self,
89       Handle<Class> view_array_class,
90       bool native_byte_order,
91       int32_t access_modes_bit_mask)
92       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
93     StackHandleScope<4> hs(self);
94     Handle<ByteArrayViewVarHandle> bvh = hs.NewHandle(
95         ObjPtr<ByteArrayViewVarHandle>::DownCast(
96             GetClassRoot<ByteArrayViewVarHandle>()->AllocObject(self)));
97 
98     // Initialize super class fields
99     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
100     Handle<Class> var_type = hs.NewHandle(view_array_class->GetComponentType());
101     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
102     Handle<Class> byte_array_class(hs.NewHandle(GetClassRoot<mirror::ByteArray>()));
103     InitializeVarHandle(bvh.Get(), var_type, byte_array_class, index_type, access_modes_bit_mask);
104     bvh->SetFieldBoolean<false>(ByteArrayViewVarHandle::NativeByteOrderOffset(), native_byte_order);
105     return bvh.Get();
106   }
107 
CreateByteBufferViewVarHandle(Thread * const self,Handle<Class> view_array_class,bool native_byte_order,int32_t access_modes_bit_mask)108   static ObjPtr<ByteBufferViewVarHandle> CreateByteBufferViewVarHandle(
109       Thread* const self,
110       Handle<Class> view_array_class,
111       bool native_byte_order,
112       int32_t access_modes_bit_mask)
113       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
114     StackHandleScope<5> hs(self);
115     Handle<ByteBufferViewVarHandle> bvh = hs.NewHandle(
116         ObjPtr<ByteBufferViewVarHandle>::DownCast(
117             GetClassRoot<ByteArrayViewVarHandle>()->AllocObject(self)));
118     // Initialize super class fields
119     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
120     Handle<Class> var_type = hs.NewHandle(view_array_class->GetComponentType());
121     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
122     Handle<ClassLoader> boot_class_loader;
123     Handle<Class> byte_buffer_class = hs.NewHandle(
124         class_linker->FindSystemClass(self, "Ljava/nio/ByteBuffer;"));
125     InitializeVarHandle(bvh.Get(), var_type, byte_buffer_class, index_type, access_modes_bit_mask);
126     bvh->SetFieldBoolean<false>(ByteBufferViewVarHandle::NativeByteOrderOffset(),
127                                 native_byte_order);
128     return bvh.Get();
129   }
130 
AccessModesBitMask(VarHandle::AccessMode mode)131   static int32_t AccessModesBitMask(VarHandle::AccessMode mode) {
132     return 1 << static_cast<int32_t>(mode);
133   }
134 
135   template<typename... Args>
AccessModesBitMask(VarHandle::AccessMode first,Args...args)136   static int32_t AccessModesBitMask(VarHandle::AccessMode first, Args... args) {
137     return AccessModesBitMask(first) | AccessModesBitMask(args...);
138   }
139 
140  private:
InitializeVarHandle(ObjPtr<VarHandle> vh,Handle<Class> var_type,int32_t access_modes_bit_mask)141   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
142                                   Handle<Class> var_type,
143                                   int32_t access_modes_bit_mask)
144       REQUIRES_SHARED(Locks::mutator_lock_) {
145     vh->SetFieldObject<false>(VarHandle::VarTypeOffset(), var_type.Get());
146     vh->SetField32<false>(VarHandle::AccessModesBitMaskOffset(), access_modes_bit_mask);
147   }
148 
InitializeVarHandle(ObjPtr<VarHandle> vh,Handle<Class> var_type,Handle<Class> coordinate_type0,int32_t access_modes_bit_mask)149   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
150                                   Handle<Class> var_type,
151                                   Handle<Class> coordinate_type0,
152                                   int32_t access_modes_bit_mask)
153       REQUIRES_SHARED(Locks::mutator_lock_) {
154     InitializeVarHandle(vh, var_type, access_modes_bit_mask);
155     vh->SetFieldObject<false>(VarHandle::CoordinateType0Offset(), coordinate_type0.Get());
156   }
157 
InitializeVarHandle(ObjPtr<VarHandle> vh,Handle<Class> var_type,Handle<Class> coordinate_type0,Handle<Class> coordinate_type1,int32_t access_modes_bit_mask)158   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
159                                   Handle<Class> var_type,
160                                   Handle<Class> coordinate_type0,
161                                   Handle<Class> coordinate_type1,
162                                   int32_t access_modes_bit_mask)
163       REQUIRES_SHARED(Locks::mutator_lock_) {
164     InitializeVarHandle(vh, var_type, access_modes_bit_mask);
165     vh->SetFieldObject<false>(VarHandle::CoordinateType0Offset(), coordinate_type0.Get());
166     vh->SetFieldObject<false>(VarHandle::CoordinateType1Offset(), coordinate_type1.Get());
167   }
168 };
169 
170 // Convenience method for constructing MethodType instances from
171 // well-formed method descriptors.
MethodTypeOf(const std::string & method_descriptor)172 static ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor) {
173   std::vector<std::string> descriptors;
174 
175   auto it = method_descriptor.cbegin();
176   if (*it++ != '(') {
177     LOG(FATAL) << "Bad descriptor: " << method_descriptor;
178   }
179 
180   bool returnValueSeen = false;
181   const char* prefix = "";
182   for (; it != method_descriptor.cend() && !returnValueSeen; ++it) {
183     switch (*it) {
184       case ')':
185         descriptors.push_back(std::string(++it, method_descriptor.cend()));
186         returnValueSeen = true;
187         break;
188       case '[':
189         prefix = "[";
190         break;
191       case 'Z':
192       case 'B':
193       case 'C':
194       case 'S':
195       case 'I':
196       case 'J':
197       case 'F':
198       case 'D':
199         descriptors.push_back(prefix + std::string(it, it + 1));
200         prefix = "";
201         break;
202       case 'L': {
203         auto last = it + 1;
204         while (*last != ';') {
205           ++last;
206         }
207         descriptors.push_back(prefix + std::string(it, last + 1));
208         prefix = "";
209         it = last;
210         break;
211       }
212       default:
213         LOG(FATAL) << "Bad descriptor: " << method_descriptor;
214     }
215   }
216 
217   Runtime* const runtime = Runtime::Current();
218   ClassLinker* const class_linker = runtime->GetClassLinker();
219   Thread* const self = Thread::Current();
220 
221   ScopedObjectAccess soa(self);
222   StackHandleScope<3> hs(self);
223   int ptypes_count = static_cast<int>(descriptors.size()) - 1;
224   ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
225   Handle<ObjectArray<Class>> ptypes = hs.NewHandle(
226       ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count));
227   Handle<mirror::ClassLoader> boot_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
228   for (int i = 0; i < ptypes_count; ++i) {
229     ptypes->Set(i, class_linker->FindClass(self, descriptors[i].c_str(), boot_class_loader));
230   }
231   Handle<Class> rtype =
232       hs.NewHandle(class_linker->FindClass(self, descriptors.back().c_str(), boot_class_loader));
233   return MethodType::Create(self, rtype, ptypes);
234 }
235 
AccessModeMatch(ObjPtr<VarHandle> vh,VarHandle::AccessMode access_mode,ObjPtr<MethodType> method_type,VarHandle::MatchKind expected_match)236 static bool AccessModeMatch(ObjPtr<VarHandle> vh,
237                             VarHandle::AccessMode access_mode,
238                             ObjPtr<MethodType> method_type,
239                             VarHandle::MatchKind expected_match)
240     REQUIRES_SHARED(Locks::mutator_lock_) {
241   return vh->GetMethodTypeMatchForAccessMode(access_mode, method_type) == expected_match;
242 }
243 
244 template <typename VH>
AccessModeExactMatch(Handle<VH> vh,VarHandle::AccessMode access_mode,const char * descriptor)245 static bool AccessModeExactMatch(Handle<VH> vh,
246                                  VarHandle::AccessMode access_mode,
247                                  const char* descriptor)
248     REQUIRES_SHARED(Locks::mutator_lock_) {
249   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
250   return AccessModeMatch(vh.Get(),
251                          access_mode,
252                          method_type,
253                          VarHandle::MatchKind::kExact);
254 }
255 
256 template <typename VH>
AccessModeWithConversionsMatch(Handle<VH> vh,VarHandle::AccessMode access_mode,const char * descriptor)257 static bool AccessModeWithConversionsMatch(Handle<VH> vh,
258                                           VarHandle::AccessMode access_mode,
259                                           const char* descriptor)
260     REQUIRES_SHARED(Locks::mutator_lock_) {
261   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
262   return AccessModeMatch(vh.Get(),
263                          access_mode,
264                          method_type,
265                          VarHandle::MatchKind::kWithConversions);
266 }
267 
268 template <typename VH>
AccessModeNoMatch(Handle<VH> vh,VarHandle::AccessMode access_mode,const char * descriptor)269 static bool AccessModeNoMatch(Handle<VH> vh,
270                               VarHandle::AccessMode access_mode,
271                               const char* descriptor)
272     REQUIRES_SHARED(Locks::mutator_lock_) {
273   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
274   return AccessModeMatch(vh.Get(),
275                          access_mode,
276                          method_type,
277                          VarHandle::MatchKind::kNone);
278 }
279 
TEST_F(VarHandleTest,InstanceFieldVarHandle)280 TEST_F(VarHandleTest, InstanceFieldVarHandle) {
281   Thread * const self = Thread::Current();
282   ScopedObjectAccess soa(self);
283 
284   ObjPtr<Object> i = BoxPrimitive(Primitive::kPrimInt, JValue::FromPrimitive<int32_t>(37));
285   ArtField* value = i->GetClass()->FindDeclaredInstanceField("value", "I");
286   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
287                                     VarHandle::AccessMode::kGetAndSet,
288                                     VarHandle::AccessMode::kGetAndBitwiseXor);
289   StackHandleScope<6> hs(self);
290   Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask)));
291   EXPECT_FALSE(fvh.IsNull());
292   EXPECT_EQ(value, fvh->GetArtField());
293 
294   // Check access modes
295   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
296   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
297   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
298   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
299   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
300   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
301   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
302   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
303   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
304   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
305   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
306   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
307   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
308   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
309   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
310   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
311   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
312   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
313   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
314   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
315   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
316   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
317   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
318   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
319   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
320   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
321   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
322   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
323   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
324   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
325   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
326 
327   // Check compatibility - "Get" pattern
328   {
329     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
330     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;)I"));
331     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;)V"));
332     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;)D"));
333     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
334     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)Z"));
335   }
336 
337   // Check compatibility - "Set" pattern
338   {
339     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
340     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)V"));
341     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;S)V"));
342     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)V"));
343     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
344     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
345   }
346 
347   // Check compatibility - "CompareAndSet" pattern
348   {
349     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
350     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)Z"));
351     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)V"));
352     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;II)Ljava/lang/Boolean;"));
353     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;IB)V"));
354     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;II)I"));
355     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
356     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
357   }
358 
359   // Check compatibility - "CompareAndExchange" pattern
360   {
361     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
362     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)I"));
363     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)V"));
364     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;II)J"));
365     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;BS)F"));
366     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;I)Z"));
367     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(IIII)V"));
368   }
369 
370   // Check compatibility - "GetAndUpdate" pattern
371   {
372     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
373     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)I"));
374     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)V"));
375     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;I)Z"));
376     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)S"));
377   }
378 
379   // Check synthesized method types match expected forms.
380   {
381     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;)I"));
382     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;I)V"));
383     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;II)Z"));
384     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;II)I"));
385     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;I)I"));
386     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
387         REQUIRES_SHARED(Locks::mutator_lock_) {
388       return fvh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
389     };
390     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
391     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
392     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
393     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
394     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
395     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
396     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
397     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
398     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
399     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
400     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
401     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
402     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
403     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
404     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
405     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
406     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
407     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
408     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
409     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
410     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
411     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
412     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
413     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
414     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
415     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
416     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
417     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
418     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
419     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
420     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
421   }
422 }
423 
TEST_F(VarHandleTest,AccessModeTemplate)424 TEST_F(VarHandleTest, AccessModeTemplate) {
425   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
426             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGet));
427   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
428             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSet));
429   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
430             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetVolatile));
431   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
432             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetVolatile));
433   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
434             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAcquire));
435   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
436             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetRelease));
437   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
438             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetOpaque));
439   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
440             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetOpaque));
441   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
442             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndSet));
443   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
444             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchange));
445   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
446             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeAcquire));
447   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
448             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeRelease));
449   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
450             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetPlain));
451   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
452             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSet));
453   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
454             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
455   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
456             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetRelease));
457   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
458             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSet));
459   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
460             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetAcquire));
461   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
462             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetRelease));
463   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
464             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOr));
465   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
466             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
467   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
468             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
469   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
470             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAnd));
471   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
472             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
473   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
474             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
475   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
476             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXor));
477   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
478             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
479   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
480             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
481 }
482 
TEST_F(VarHandleTest,StaticFieldVarHandle)483 TEST_F(VarHandleTest, StaticFieldVarHandle) {
484   Thread * const self = Thread::Current();
485   ScopedObjectAccess soa(self);
486 
487   ObjPtr<Object> i = BoxPrimitive(Primitive::kPrimInt, JValue::FromPrimitive<int32_t>(37));
488   ArtField* value = i->GetClass()->FindDeclaredStaticField("MIN_VALUE", "I");
489   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kSet,
490                                     VarHandle::AccessMode::kGetOpaque,
491                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease);
492   StackHandleScope<6> hs(self);
493   Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask)));
494   EXPECT_FALSE(fvh.IsNull());
495   EXPECT_EQ(value, fvh->GetArtField());
496 
497   // Check access modes
498   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
499   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
500   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
501   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
502   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
503   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
504   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
505   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
506   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
507   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
508   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
509   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
510   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
511   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
512   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
513   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
514   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
515   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
516   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
517   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
518   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
519   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
520   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
521   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
522   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
523   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
524   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
525   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
526   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
527   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
528   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
529 
530   // Check compatibility - "Get" pattern
531   {
532     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
533     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "()I"));
534     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "()V"));
535     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
536     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)Z"));
537   }
538 
539   // Check compatibility - "Set" pattern
540   {
541     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
542     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)V"));
543     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()V"));
544     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
545     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(F)V"));
546   }
547 
548   // Check compatibility - "CompareAndSet" pattern
549   {
550     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
551     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)Z"));
552     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)Ljava/lang/String;"));
553     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
554     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
555   }
556 
557   // Check compatibility - "CompareAndExchange" pattern
558   {
559     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
560     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)I"));
561     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)V"));
562     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(ID)I"));
563     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)S"));
564     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(IIJ)V"));
565   }
566 
567   // Check compatibility - "GetAndUpdate" pattern
568   {
569     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
570     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)I"));
571     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)V"));
572     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(I)Z"));
573     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)V"));
574   }
575 
576   // Check synthesized method types match expected forms.
577   {
578     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("()I"));
579     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(I)V"));
580     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(II)Z"));
581     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("(II)I"));
582     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(I)I"));
583     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
584         REQUIRES_SHARED(Locks::mutator_lock_) {
585       return fvh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
586     };
587     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
588     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
589     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
590     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
591     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
592     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
593     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
594     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
595     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
596     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
597     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
598     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
599     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
600     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
601     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
602     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
603     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
604     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
605     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
606     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
607     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
608     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
609     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
610     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
611     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
612     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
613     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
614     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
615     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
616     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
617     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
618   }
619 }
620 
TEST_F(VarHandleTest,ArrayElementVarHandle)621 TEST_F(VarHandleTest, ArrayElementVarHandle) {
622   Thread * const self = Thread::Current();
623   ScopedObjectAccess soa(self);
624   StackHandleScope<7> hs(self);
625 
626   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
627                                     VarHandle::AccessMode::kSet,
628                                     VarHandle::AccessMode::kGetVolatile,
629                                     VarHandle::AccessMode::kSetVolatile,
630                                     VarHandle::AccessMode::kGetAcquire,
631                                     VarHandle::AccessMode::kSetRelease,
632                                     VarHandle::AccessMode::kGetOpaque,
633                                     VarHandle::AccessMode::kSetOpaque,
634                                     VarHandle::AccessMode::kCompareAndSet,
635                                     VarHandle::AccessMode::kCompareAndExchange,
636                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
637                                     VarHandle::AccessMode::kCompareAndExchangeRelease,
638                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
639                                     VarHandle::AccessMode::kWeakCompareAndSet,
640                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
641                                     VarHandle::AccessMode::kWeakCompareAndSetRelease,
642                                     VarHandle::AccessMode::kGetAndSet,
643                                     VarHandle::AccessMode::kGetAndSetAcquire,
644                                     VarHandle::AccessMode::kGetAndSetRelease,
645                                     VarHandle::AccessMode::kGetAndAdd,
646                                     VarHandle::AccessMode::kGetAndAddAcquire,
647                                     VarHandle::AccessMode::kGetAndAddRelease,
648                                     VarHandle::AccessMode::kGetAndBitwiseOr,
649                                     VarHandle::AccessMode::kGetAndBitwiseOrRelease,
650                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
651                                     VarHandle::AccessMode::kGetAndBitwiseAnd,
652                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
653                                     VarHandle::AccessMode::kGetAndBitwiseAndAcquire,
654                                     VarHandle::AccessMode::kGetAndBitwiseXor,
655                                     VarHandle::AccessMode::kGetAndBitwiseXorRelease,
656                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
657 
658   Handle<mirror::Class> string_array_class = hs.NewHandle(
659       GetClassRoot<mirror::ObjectArray<mirror::String>>());
660   Handle<mirror::ArrayElementVarHandle> vh(
661       hs.NewHandle(CreateArrayElementVarHandle(self, string_array_class, mask)));
662   EXPECT_FALSE(vh.IsNull());
663 
664   // Check access modes
665   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
666   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
667   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
668   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
669   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
670   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
671   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
672   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
673   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
674   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
675   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
676   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
677   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
678   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
679   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
680   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
681   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
682   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
683   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
684   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
685   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
686   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
687   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
688   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
689   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
690   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
691   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
692   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
693   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
694   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
695   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
696 
697   // Check compatibility - "Get" pattern
698   {
699     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
700     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;I)Ljava/lang/String;"));
701     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;I)V"));
702     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;Ljava/lang/String;)Z"));
703     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
704   }
705 
706   // Check compatibility - "Set" pattern
707   {
708     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
709     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)V"));
710     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)V"));
711     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)Z"));
712     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
713   }
714 
715   // Check compatibility - "CompareAndSet" pattern
716   {
717     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
718     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z"));
719     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;III)I"));
720     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)Z"));
721     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
722   }
723 
724   // Check compatibility - "CompareAndExchange" pattern
725   {
726     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
727     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
728     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"));
729     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;II)Z"));
730     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
731   }
732 
733   // Check compatibility - "GetAndUpdate" pattern
734   {
735     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
736     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;"));
737     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)V"));
738     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)Z"));
739     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
740   }
741 
742   // Check synthesized method types match expected forms.
743   {
744     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("([Ljava/lang/String;I)Ljava/lang/String;"));
745     Handle<MethodType> set =
746         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)V"));
747     Handle<MethodType> compareAndSet =
748         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z"));
749     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf(
750         "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
751     Handle<MethodType> getAndUpdate =
752         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;"));
753     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
754         REQUIRES_SHARED(Locks::mutator_lock_) {
755       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
756     };
757     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
758     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
759     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
760     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
761     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
762     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
763     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
764     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
765     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
766     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
767     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
768     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
769     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
770     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
771     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
772     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
773     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
774     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
775     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
776     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
777     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
778     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
779     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
780     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
781     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
782     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
783     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
784     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
785     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
786     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
787     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
788   }
789 }
790 
TEST_F(VarHandleTest,ByteArrayViewVarHandle)791 TEST_F(VarHandleTest, ByteArrayViewVarHandle) {
792   Thread * const self = Thread::Current();
793   ScopedObjectAccess soa(self);
794   StackHandleScope<7> hs(self);
795 
796   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
797                                     VarHandle::AccessMode::kGetVolatile,
798                                     VarHandle::AccessMode::kGetAcquire,
799                                     VarHandle::AccessMode::kGetOpaque,
800                                     VarHandle::AccessMode::kCompareAndSet,
801                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
802                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
803                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
804                                     VarHandle::AccessMode::kGetAndSet,
805                                     VarHandle::AccessMode::kGetAndSetRelease,
806                                     VarHandle::AccessMode::kGetAndAddAcquire,
807                                     VarHandle::AccessMode::kGetAndBitwiseOr,
808                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
809                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
810                                     VarHandle::AccessMode::kGetAndBitwiseXor,
811                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
812 
813   Handle<Class> char_array_class(hs.NewHandle(GetClassRoot<mirror::CharArray>()));
814   const bool native_byte_order = true;
815   Handle<mirror::ByteArrayViewVarHandle> vh(
816       hs.NewHandle(CreateByteArrayViewVarHandle(self, char_array_class, native_byte_order, mask)));
817   EXPECT_FALSE(vh.IsNull());
818   EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
819 
820   // Check access modes
821   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
822   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
823   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
824   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
825   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
826   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
827   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
828   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
829   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
830   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
831   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
832   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
833   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
834   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
835   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
836   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
837   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
838   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
839   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
840   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
841   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
842   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
843   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
844   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
845   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
846   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
847   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
848   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
849   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
850   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
851   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
852 
853   // Check compatibility - "Get" pattern
854   {
855     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
856     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BI)C"));
857     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BI)V"));
858     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BC)Z"));
859     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
860   }
861 
862   // Check compatibility - "Set" pattern
863   {
864     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
865     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)V"));
866     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)V"));
867     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)Z"));
868     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
869   }
870 
871   // Check compatibility - "CompareAndSet" pattern
872   {
873     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
874     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)Z"));
875     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BIII)I"));
876     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)Z"));
877     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
878   }
879 
880   // Check compatibility - "CompareAndExchange" pattern
881   {
882     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
883     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)C"));
884     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)V"));
885     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BII)Z"));
886     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
887   }
888 
889   // Check compatibility - "GetAndUpdate" pattern
890   {
891     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
892     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)C"));
893     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)V"));
894     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BIC)Z"));
895     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
896   }
897 
898   // Check synthesized method types match expected forms.
899   {
900     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("([BI)C"));
901     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("([BIC)V"));
902     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("([BICC)Z"));
903     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("([BICC)C"));
904     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("([BIC)C"));
905     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
906         REQUIRES_SHARED(Locks::mutator_lock_) {
907       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
908     };
909     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
910     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
911     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
912     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
913     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
914     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
915     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
916     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
917     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
918     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
919     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
920     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
921     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
922     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
923     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
924     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
925     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
926     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
927     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
928     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
929     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
930     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
931     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
932     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
933     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
934     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
935     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
936     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
937     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
938     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
939     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
940   }
941 }
942 
TEST_F(VarHandleTest,ByteBufferViewVarHandle)943 TEST_F(VarHandleTest, ByteBufferViewVarHandle) {
944   Thread * const self = Thread::Current();
945   ScopedObjectAccess soa(self);
946   StackHandleScope<7> hs(self);
947 
948   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
949                                     VarHandle::AccessMode::kGetVolatile,
950                                     VarHandle::AccessMode::kGetAcquire,
951                                     VarHandle::AccessMode::kGetOpaque,
952                                     VarHandle::AccessMode::kCompareAndSet,
953                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
954                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
955                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
956                                     VarHandle::AccessMode::kGetAndSet,
957                                     VarHandle::AccessMode::kGetAndSetRelease,
958                                     VarHandle::AccessMode::kGetAndAddAcquire,
959                                     VarHandle::AccessMode::kGetAndBitwiseOr,
960                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
961                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
962                                     VarHandle::AccessMode::kGetAndBitwiseXor,
963                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
964 
965   Handle<Class> double_array_class(hs.NewHandle(GetClassRoot<mirror::DoubleArray>()));
966   const bool native_byte_order = false;
967   Handle<mirror::ByteBufferViewVarHandle> vh(hs.NewHandle(
968       CreateByteBufferViewVarHandle(self, double_array_class, native_byte_order, mask)));
969   EXPECT_FALSE(vh.IsNull());
970   EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
971 
972   // Check access modes
973   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
974   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
975   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
976   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
977   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
978   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
979   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
980   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
981   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
982   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
983   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
984   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
985   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
986   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
987   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
988   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
989   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
990   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
991   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
992   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
993   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
994   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
995   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
996   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
997   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
998   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
999   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
1000   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
1001   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
1002   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
1003   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
1004 
1005   // Check compatibility - "Get" pattern
1006   {
1007     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
1008     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)D"));
1009     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)V"));
1010     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;D)Z"));
1011     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
1012   }
1013 
1014   // Check compatibility - "Set" pattern
1015   {
1016     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
1017     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)V"));
1018     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)V"));
1019     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)Z"));
1020     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
1021   }
1022 
1023   // Check compatibility - "CompareAndSet" pattern
1024   {
1025     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
1026     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)Z"));
1027     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDI)D"));
1028     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)Z"));
1029     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
1030   }
1031 
1032   // Check compatibility - "CompareAndExchange" pattern
1033   {
1034     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
1035     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)D"));
1036     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)V"));
1037     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;II)Z"));
1038     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
1039   }
1040 
1041   // Check compatibility - "GetAndUpdate" pattern
1042   {
1043     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
1044     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)D"));
1045     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)V"));
1046     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)Z"));
1047     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
1048   }
1049 
1050   // Check synthesized method types match expected forms.
1051   {
1052     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;I)D"));
1053     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;ID)V"));
1054     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)Z"));
1055     Handle<MethodType> compareAndExchange =
1056         hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)D"));
1057     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;ID)D"));
1058     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
1059         REQUIRES_SHARED(Locks::mutator_lock_) {
1060       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
1061     };
1062     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
1063     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
1064     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
1065     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
1066     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
1067     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
1068     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
1069     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
1070     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
1071     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
1072     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
1073     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
1074     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
1075     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
1076     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
1077     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
1078     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
1079     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
1080     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
1081     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
1082     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
1083     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
1084     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
1085     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
1086     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
1087     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
1088     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
1089     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
1090     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
1091     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
1092     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
1093   }
1094 }
1095 
TEST_F(VarHandleTest,GetMethodTypeForAccessMode)1096 TEST_F(VarHandleTest, GetMethodTypeForAccessMode) {
1097   VarHandle::AccessMode access_mode;
1098 
1099   // Invalid access mode names
1100   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName(nullptr, &access_mode));
1101   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("", &access_mode));
1102   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("CompareAndExchange", &access_mode));
1103   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("compareAndExchangX", &access_mode));
1104 
1105   // Valid access mode names
1106   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchange", &access_mode));
1107   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchange, access_mode);
1108   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchangeAcquire", &access_mode));
1109   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchangeAcquire, access_mode);
1110   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchangeRelease", &access_mode));
1111   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchangeRelease, access_mode);
1112   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndSet", &access_mode));
1113   EXPECT_EQ(VarHandle::AccessMode::kCompareAndSet, access_mode);
1114   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("get", &access_mode));
1115   EXPECT_EQ(VarHandle::AccessMode::kGet, access_mode);
1116   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAcquire", &access_mode));
1117   EXPECT_EQ(VarHandle::AccessMode::kGetAcquire, access_mode);
1118   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAdd", &access_mode));
1119   EXPECT_EQ(VarHandle::AccessMode::kGetAndAdd, access_mode);
1120   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAddAcquire", &access_mode));
1121   EXPECT_EQ(VarHandle::AccessMode::kGetAndAddAcquire, access_mode);
1122   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAddRelease", &access_mode));
1123   EXPECT_EQ(VarHandle::AccessMode::kGetAndAddRelease, access_mode);
1124   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAnd", &access_mode));
1125   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAnd, access_mode);
1126   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAndAcquire", &access_mode));
1127   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, access_mode);
1128   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAndRelease", &access_mode));
1129   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAndRelease, access_mode);
1130   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOr", &access_mode));
1131   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOr, access_mode);
1132   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOrAcquire", &access_mode));
1133   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, access_mode);
1134   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOrRelease", &access_mode));
1135   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOrRelease, access_mode);
1136   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXor", &access_mode));
1137   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXor, access_mode);
1138   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXorAcquire", &access_mode));
1139   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, access_mode);
1140   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXorRelease", &access_mode));
1141   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXorRelease, access_mode);
1142   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSet", &access_mode));
1143   EXPECT_EQ(VarHandle::AccessMode::kGetAndSet, access_mode);
1144   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSetAcquire", &access_mode));
1145   EXPECT_EQ(VarHandle::AccessMode::kGetAndSetAcquire, access_mode);
1146   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSetRelease", &access_mode));
1147   EXPECT_EQ(VarHandle::AccessMode::kGetAndSetRelease, access_mode);
1148   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getOpaque", &access_mode));
1149   EXPECT_EQ(VarHandle::AccessMode::kGetOpaque, access_mode);
1150   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getVolatile", &access_mode));
1151   EXPECT_EQ(VarHandle::AccessMode::kGetVolatile, access_mode);
1152   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("set", &access_mode));
1153   EXPECT_EQ(VarHandle::AccessMode::kSet, access_mode);
1154   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setOpaque", &access_mode));
1155   EXPECT_EQ(VarHandle::AccessMode::kSetOpaque, access_mode);
1156   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setRelease", &access_mode));
1157   EXPECT_EQ(VarHandle::AccessMode::kSetRelease, access_mode);
1158   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setVolatile", &access_mode));
1159   EXPECT_EQ(VarHandle::AccessMode::kSetVolatile, access_mode);
1160   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSet", &access_mode));
1161   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSet, access_mode);
1162   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetAcquire", &access_mode));
1163   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetAcquire, access_mode);
1164   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetPlain", &access_mode));
1165   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetPlain, access_mode);
1166   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetRelease", &access_mode));
1167   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetRelease, access_mode);
1168 }
1169 
1170 }  // namespace mirror
1171 }  // namespace art
1172