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