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