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