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