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