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