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