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