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