1168 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			1168 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2017 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #include "var_handle.h"
 | |
| 
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| #include "art_field-inl.h"
 | |
| #include "class-alloc-inl.h"
 | |
| #include "class-inl.h"
 | |
| #include "class_linker-inl.h"
 | |
| #include "class_loader.h"
 | |
| #include "class_root-inl.h"
 | |
| #include "common_runtime_test.h"
 | |
| #include "handle_scope-inl.h"
 | |
| #include "jvalue-inl.h"
 | |
| #include "method_type.h"
 | |
| #include "object_array-alloc-inl.h"
 | |
| #include "object_array-inl.h"
 | |
| #include "reflection.h"
 | |
| #include "scoped_thread_state_change-inl.h"
 | |
| 
 | |
| namespace art {
 | |
| namespace mirror {
 | |
| 
 | |
| // Tests for mirror::VarHandle and it's descendents.
 | |
| class VarHandleTest : public CommonRuntimeTest {
 | |
|  public:
 | |
|   static ObjPtr<FieldVarHandle> CreateFieldVarHandle(Thread* const self,
 | |
|                                                      ArtField* art_field,
 | |
|                                                      int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
 | |
|     StackHandleScope<4> hs(self);
 | |
|     Handle<FieldVarHandle> fvh = hs.NewHandle(
 | |
|         ObjPtr<FieldVarHandle>::DownCast(GetClassRoot<FieldVarHandle>()->AllocObject(self)));
 | |
|     Handle<Class> var_type = hs.NewHandle(art_field->ResolveType());
 | |
| 
 | |
|     if (art_field->IsStatic()) {
 | |
|       InitializeVarHandle(fvh.Get(), var_type, access_modes_bit_mask);
 | |
|     } else {
 | |
|       Handle<Class> declaring_type = hs.NewHandle(art_field->GetDeclaringClass());
 | |
|       InitializeVarHandle(fvh.Get(),
 | |
|                           var_type,
 | |
|                           declaring_type,
 | |
|                           access_modes_bit_mask);
 | |
|     }
 | |
|     uintptr_t opaque_field = reinterpret_cast<uintptr_t>(art_field);
 | |
|     fvh->SetField64<false>(FieldVarHandle::ArtFieldOffset(), opaque_field);
 | |
|     return fvh.Get();
 | |
|   }
 | |
| 
 | |
|   static ObjPtr<ArrayElementVarHandle> CreateArrayElementVarHandle(Thread* const self,
 | |
|                                                                    Handle<Class> array_class,
 | |
|                                                                    int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
 | |
|     StackHandleScope<3> hs(self);
 | |
|     Handle<ArrayElementVarHandle> vh = hs.NewHandle(
 | |
|         ObjPtr<ArrayElementVarHandle>::DownCast(
 | |
|             GetClassRoot<ArrayElementVarHandle>()->AllocObject(self)));
 | |
| 
 | |
|     // Initialize super class fields
 | |
|     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 | |
|     Handle<Class> var_type = hs.NewHandle(array_class->GetComponentType());
 | |
|     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
 | |
|     InitializeVarHandle(vh.Get(), var_type, array_class, index_type, access_modes_bit_mask);
 | |
|     return vh.Get();
 | |
|   }
 | |
| 
 | |
|   static ObjPtr<ByteArrayViewVarHandle> CreateByteArrayViewVarHandle(
 | |
|       Thread* const self,
 | |
|       Handle<Class> view_array_class,
 | |
|       bool native_byte_order,
 | |
|       int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
 | |
|     StackHandleScope<4> hs(self);
 | |
|     Handle<ByteArrayViewVarHandle> bvh = hs.NewHandle(
 | |
|         ObjPtr<ByteArrayViewVarHandle>::DownCast(
 | |
|             GetClassRoot<ByteArrayViewVarHandle>()->AllocObject(self)));
 | |
| 
 | |
|     // Initialize super class fields
 | |
|     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 | |
|     Handle<Class> var_type = hs.NewHandle(view_array_class->GetComponentType());
 | |
|     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
 | |
|     Handle<Class> byte_array_class(hs.NewHandle(GetClassRoot<mirror::ByteArray>()));
 | |
|     InitializeVarHandle(bvh.Get(), var_type, byte_array_class, index_type, access_modes_bit_mask);
 | |
|     bvh->SetFieldBoolean<false>(ByteArrayViewVarHandle::NativeByteOrderOffset(), native_byte_order);
 | |
|     return bvh.Get();
 | |
|   }
 | |
| 
 | |
|   static ObjPtr<ByteBufferViewVarHandle> CreateByteBufferViewVarHandle(
 | |
|       Thread* const self,
 | |
|       Handle<Class> view_array_class,
 | |
|       bool native_byte_order,
 | |
|       int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
 | |
|     StackHandleScope<5> hs(self);
 | |
|     Handle<ByteBufferViewVarHandle> bvh = hs.NewHandle(
 | |
|         ObjPtr<ByteBufferViewVarHandle>::DownCast(
 | |
|             GetClassRoot<ByteArrayViewVarHandle>()->AllocObject(self)));
 | |
|     // Initialize super class fields
 | |
|     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 | |
|     Handle<Class> var_type = hs.NewHandle(view_array_class->GetComponentType());
 | |
|     Handle<Class> index_type = hs.NewHandle(class_linker->FindPrimitiveClass('I'));
 | |
|     Handle<ClassLoader> boot_class_loader;
 | |
|     Handle<Class> byte_buffer_class = hs.NewHandle(
 | |
|         class_linker->FindSystemClass(self, "Ljava/nio/ByteBuffer;"));
 | |
|     InitializeVarHandle(bvh.Get(), var_type, byte_buffer_class, index_type, access_modes_bit_mask);
 | |
|     bvh->SetFieldBoolean<false>(ByteBufferViewVarHandle::NativeByteOrderOffset(),
 | |
|                                 native_byte_order);
 | |
|     return bvh.Get();
 | |
|   }
 | |
| 
 | |
|   static int32_t AccessModesBitMask(VarHandle::AccessMode mode) {
 | |
|     return 1 << static_cast<int32_t>(mode);
 | |
|   }
 | |
| 
 | |
|   template<typename... Args>
 | |
|   static int32_t AccessModesBitMask(VarHandle::AccessMode first, Args... args) {
 | |
|     return AccessModesBitMask(first) | AccessModesBitMask(args...);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
 | |
|                                   Handle<Class> var_type,
 | |
|                                   int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     vh->SetFieldObject<false>(VarHandle::VarTypeOffset(), var_type.Get());
 | |
|     vh->SetField32<false>(VarHandle::AccessModesBitMaskOffset(), access_modes_bit_mask);
 | |
|   }
 | |
| 
 | |
|   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
 | |
|                                   Handle<Class> var_type,
 | |
|                                   Handle<Class> coordinate_type0,
 | |
|                                   int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     InitializeVarHandle(vh, var_type, access_modes_bit_mask);
 | |
|     vh->SetFieldObject<false>(VarHandle::CoordinateType0Offset(), coordinate_type0.Get());
 | |
|   }
 | |
| 
 | |
|   static void InitializeVarHandle(ObjPtr<VarHandle> vh,
 | |
|                                   Handle<Class> var_type,
 | |
|                                   Handle<Class> coordinate_type0,
 | |
|                                   Handle<Class> coordinate_type1,
 | |
|                                   int32_t access_modes_bit_mask)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|     InitializeVarHandle(vh, var_type, access_modes_bit_mask);
 | |
|     vh->SetFieldObject<false>(VarHandle::CoordinateType0Offset(), coordinate_type0.Get());
 | |
|     vh->SetFieldObject<false>(VarHandle::CoordinateType1Offset(), coordinate_type1.Get());
 | |
|   }
 | |
| };
 | |
| 
 | |
| // Convenience method for constructing MethodType instances from
 | |
| // well-formed method descriptors.
 | |
| static ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor) {
 | |
|   std::vector<std::string> descriptors;
 | |
| 
 | |
|   auto it = method_descriptor.cbegin();
 | |
|   if (*it++ != '(') {
 | |
|     LOG(FATAL) << "Bad descriptor: " << method_descriptor;
 | |
|   }
 | |
| 
 | |
|   bool returnValueSeen = false;
 | |
|   const char* prefix = "";
 | |
|   for (; it != method_descriptor.cend() && !returnValueSeen; ++it) {
 | |
|     switch (*it) {
 | |
|       case ')':
 | |
|         descriptors.push_back(std::string(++it, method_descriptor.cend()));
 | |
|         returnValueSeen = true;
 | |
|         break;
 | |
|       case '[':
 | |
|         prefix = "[";
 | |
|         break;
 | |
|       case 'Z':
 | |
|       case 'B':
 | |
|       case 'C':
 | |
|       case 'S':
 | |
|       case 'I':
 | |
|       case 'J':
 | |
|       case 'F':
 | |
|       case 'D':
 | |
|         descriptors.push_back(prefix + std::string(it, it + 1));
 | |
|         prefix = "";
 | |
|         break;
 | |
|       case 'L': {
 | |
|         auto last = it + 1;
 | |
|         while (*last != ';') {
 | |
|           ++last;
 | |
|         }
 | |
|         descriptors.push_back(prefix + std::string(it, last + 1));
 | |
|         prefix = "";
 | |
|         it = last;
 | |
|         break;
 | |
|       }
 | |
|       default:
 | |
|         LOG(FATAL) << "Bad descriptor: " << method_descriptor;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Runtime* const runtime = Runtime::Current();
 | |
|   ClassLinker* const class_linker = runtime->GetClassLinker();
 | |
|   Thread* const self = Thread::Current();
 | |
| 
 | |
|   ScopedObjectAccess soa(self);
 | |
|   StackHandleScope<3> hs(self);
 | |
|   int ptypes_count = static_cast<int>(descriptors.size()) - 1;
 | |
|   ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
 | |
|   Handle<ObjectArray<Class>> ptypes = hs.NewHandle(
 | |
|       ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count));
 | |
|   Handle<mirror::ClassLoader> boot_class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
 | |
|   for (int i = 0; i < ptypes_count; ++i) {
 | |
|     ptypes->Set(i, class_linker->FindClass(self, descriptors[i].c_str(), boot_class_loader));
 | |
|   }
 | |
|   Handle<Class> rtype =
 | |
|       hs.NewHandle(class_linker->FindClass(self, descriptors.back().c_str(), boot_class_loader));
 | |
|   return MethodType::Create(self, rtype, ptypes);
 | |
| }
 | |
| 
 | |
| static bool AccessModeMatch(ObjPtr<VarHandle> vh,
 | |
|                             VarHandle::AccessMode access_mode,
 | |
|                             ObjPtr<MethodType> method_type,
 | |
|                             VarHandle::MatchKind expected_match)
 | |
|     REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|   return vh->GetMethodTypeMatchForAccessMode(access_mode, method_type) == expected_match;
 | |
| }
 | |
| 
 | |
| template <typename VH>
 | |
| static bool AccessModeExactMatch(Handle<VH> vh,
 | |
|                                  VarHandle::AccessMode access_mode,
 | |
|                                  const char* descriptor)
 | |
|     REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
 | |
|   return AccessModeMatch(vh.Get(),
 | |
|                          access_mode,
 | |
|                          method_type,
 | |
|                          VarHandle::MatchKind::kExact);
 | |
| }
 | |
| 
 | |
| template <typename VH>
 | |
| static bool AccessModeWithConversionsMatch(Handle<VH> vh,
 | |
|                                           VarHandle::AccessMode access_mode,
 | |
|                                           const char* descriptor)
 | |
|     REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
 | |
|   return AccessModeMatch(vh.Get(),
 | |
|                          access_mode,
 | |
|                          method_type,
 | |
|                          VarHandle::MatchKind::kWithConversions);
 | |
| }
 | |
| 
 | |
| template <typename VH>
 | |
| static bool AccessModeNoMatch(Handle<VH> vh,
 | |
|                               VarHandle::AccessMode access_mode,
 | |
|                               const char* descriptor)
 | |
|     REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|   ObjPtr<MethodType> method_type = MethodTypeOf(descriptor);
 | |
|   return AccessModeMatch(vh.Get(),
 | |
|                          access_mode,
 | |
|                          method_type,
 | |
|                          VarHandle::MatchKind::kNone);
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, InstanceFieldVarHandle) {
 | |
|   Thread * const self = Thread::Current();
 | |
|   ScopedObjectAccess soa(self);
 | |
| 
 | |
|   ObjPtr<Object> i = BoxPrimitive(Primitive::kPrimInt, JValue::FromPrimitive<int32_t>(37));
 | |
|   ArtField* value = i->GetClass()->FindDeclaredInstanceField("value", "I");
 | |
|   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
 | |
|                                     VarHandle::AccessMode::kGetAndSet,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXor);
 | |
|   StackHandleScope<6> hs(self);
 | |
|   Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask)));
 | |
|   EXPECT_FALSE(fvh.IsNull());
 | |
|   EXPECT_EQ(value, fvh->GetArtField());
 | |
| 
 | |
|   // Check access modes
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| 
 | |
|   // Check compatibility - "Get" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;)I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;)V"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;)D"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)Z"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "Set" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)V"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;S)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndSet" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)Z"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)V"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;II)Ljava/lang/Boolean;"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;IB)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;II)I"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndExchange" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;II)V"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;II)J"));
 | |
|     EXPECT_TRUE(AccessModeWithConversionsMatch(fvh, access_mode, "(Ljava/lang/Integer;BS)F"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(IIII)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "GetAndUpdate" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(Ljava/lang/Integer;I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Ljava/lang/Integer;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)S"));
 | |
|   }
 | |
| 
 | |
|   // Check synthesized method types match expected forms.
 | |
|   {
 | |
|     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;)I"));
 | |
|     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;I)V"));
 | |
|     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;II)Z"));
 | |
|     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;II)I"));
 | |
|     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(Ljava/lang/Integer;I)I"));
 | |
|     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
 | |
|         REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|       return fvh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
 | |
|     };
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, AccessModeTemplate) {
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndExchange,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kCompareAndSet,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_EQ(VarHandle::AccessModeTemplate::kGetAndUpdate,
 | |
|             VarHandle::GetAccessModeTemplate(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, StaticFieldVarHandle) {
 | |
|   Thread * const self = Thread::Current();
 | |
|   ScopedObjectAccess soa(self);
 | |
| 
 | |
|   ObjPtr<Object> i = BoxPrimitive(Primitive::kPrimInt, JValue::FromPrimitive<int32_t>(37));
 | |
|   ArtField* value = i->GetClass()->FindDeclaredStaticField("MIN_VALUE", "I");
 | |
|   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kSet,
 | |
|                                     VarHandle::AccessMode::kGetOpaque,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease);
 | |
|   StackHandleScope<6> hs(self);
 | |
|   Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask)));
 | |
|   EXPECT_FALSE(fvh.IsNull());
 | |
|   EXPECT_EQ(value, fvh->GetArtField());
 | |
| 
 | |
|   // Check access modes
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_TRUE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_FALSE(fvh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| 
 | |
|   // Check compatibility - "Get" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "()I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "()V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)Z"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "Set" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(F)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndSet" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)Ljava/lang/String;"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "()Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndExchange" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(II)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(ID)I"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)S"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(IIJ)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "GetAndUpdate" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)I"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(fvh, access_mode, "(I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(fvh, access_mode, "(II)V"));
 | |
|   }
 | |
| 
 | |
|   // Check synthesized method types match expected forms.
 | |
|   {
 | |
|     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("()I"));
 | |
|     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(I)V"));
 | |
|     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(II)Z"));
 | |
|     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("(II)I"));
 | |
|     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(I)I"));
 | |
|     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
 | |
|         REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|       return fvh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
 | |
|     };
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, ArrayElementVarHandle) {
 | |
|   Thread * const self = Thread::Current();
 | |
|   ScopedObjectAccess soa(self);
 | |
|   StackHandleScope<7> hs(self);
 | |
| 
 | |
|   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
 | |
|                                     VarHandle::AccessMode::kSet,
 | |
|                                     VarHandle::AccessMode::kGetVolatile,
 | |
|                                     VarHandle::AccessMode::kSetVolatile,
 | |
|                                     VarHandle::AccessMode::kGetAcquire,
 | |
|                                     VarHandle::AccessMode::kSetRelease,
 | |
|                                     VarHandle::AccessMode::kGetOpaque,
 | |
|                                     VarHandle::AccessMode::kSetOpaque,
 | |
|                                     VarHandle::AccessMode::kCompareAndSet,
 | |
|                                     VarHandle::AccessMode::kCompareAndExchange,
 | |
|                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
 | |
|                                     VarHandle::AccessMode::kCompareAndExchangeRelease,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSet,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndSet,
 | |
|                                     VarHandle::AccessMode::kGetAndSetAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndSetRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndAdd,
 | |
|                                     VarHandle::AccessMode::kGetAndAddAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndAddRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOr,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOrRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAnd,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAndAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXor,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXorRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
 | |
| 
 | |
|   Handle<mirror::Class> string_array_class = hs.NewHandle(
 | |
|       GetClassRoot<mirror::ObjectArray<mirror::String>>());
 | |
|   Handle<mirror::ArrayElementVarHandle> vh(
 | |
|       hs.NewHandle(CreateArrayElementVarHandle(self, string_array_class, mask)));
 | |
|   EXPECT_FALSE(vh.IsNull());
 | |
| 
 | |
|   // Check access modes
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| 
 | |
|   // Check compatibility - "Get" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;I)Ljava/lang/String;"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;Ljava/lang/String;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "Set" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndSet" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;III)I"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndExchange" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;II)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "GetAndUpdate" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([Ljava/lang/String;ILjava/lang/String;)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
 | |
|   }
 | |
| 
 | |
|   // Check synthesized method types match expected forms.
 | |
|   {
 | |
|     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("([Ljava/lang/String;I)Ljava/lang/String;"));
 | |
|     Handle<MethodType> set =
 | |
|         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)V"));
 | |
|     Handle<MethodType> compareAndSet =
 | |
|         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z"));
 | |
|     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf(
 | |
|         "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"));
 | |
|     Handle<MethodType> getAndUpdate =
 | |
|         hs.NewHandle(MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;"));
 | |
|     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
 | |
|         REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
 | |
|     };
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, ByteArrayViewVarHandle) {
 | |
|   Thread * const self = Thread::Current();
 | |
|   ScopedObjectAccess soa(self);
 | |
|   StackHandleScope<7> hs(self);
 | |
| 
 | |
|   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
 | |
|                                     VarHandle::AccessMode::kGetVolatile,
 | |
|                                     VarHandle::AccessMode::kGetAcquire,
 | |
|                                     VarHandle::AccessMode::kGetOpaque,
 | |
|                                     VarHandle::AccessMode::kCompareAndSet,
 | |
|                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndSet,
 | |
|                                     VarHandle::AccessMode::kGetAndSetRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndAddAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOr,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXor,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
 | |
| 
 | |
|   Handle<Class> char_array_class(hs.NewHandle(GetClassRoot<mirror::CharArray>()));
 | |
|   const bool native_byte_order = true;
 | |
|   Handle<mirror::ByteArrayViewVarHandle> vh(
 | |
|       hs.NewHandle(CreateByteArrayViewVarHandle(self, char_array_class, native_byte_order, mask)));
 | |
|   EXPECT_FALSE(vh.IsNull());
 | |
|   EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
 | |
| 
 | |
|   // Check access modes
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| 
 | |
|   // Check compatibility - "Get" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BI)C"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BI)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BC)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "Set" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndSet" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BIII)I"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BI)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndExchange" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)C"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BICC)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BII)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "GetAndUpdate" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)C"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "([BIC)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "([BIC)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
 | |
|   }
 | |
| 
 | |
|   // Check synthesized method types match expected forms.
 | |
|   {
 | |
|     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("([BI)C"));
 | |
|     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("([BIC)V"));
 | |
|     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("([BICC)Z"));
 | |
|     Handle<MethodType> compareAndExchange = hs.NewHandle(MethodTypeOf("([BICC)C"));
 | |
|     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("([BIC)C"));
 | |
|     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
 | |
|         REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
 | |
|     };
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, ByteBufferViewVarHandle) {
 | |
|   Thread * const self = Thread::Current();
 | |
|   ScopedObjectAccess soa(self);
 | |
|   StackHandleScope<7> hs(self);
 | |
| 
 | |
|   int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet,
 | |
|                                     VarHandle::AccessMode::kGetVolatile,
 | |
|                                     VarHandle::AccessMode::kGetAcquire,
 | |
|                                     VarHandle::AccessMode::kGetOpaque,
 | |
|                                     VarHandle::AccessMode::kCompareAndSet,
 | |
|                                     VarHandle::AccessMode::kCompareAndExchangeAcquire,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetPlain,
 | |
|                                     VarHandle::AccessMode::kWeakCompareAndSetAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndSet,
 | |
|                                     VarHandle::AccessMode::kGetAndSetRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndAddAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOr,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseOrAcquire,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseAndRelease,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXor,
 | |
|                                     VarHandle::AccessMode::kGetAndBitwiseXorAcquire);
 | |
| 
 | |
|   Handle<Class> double_array_class(hs.NewHandle(GetClassRoot<mirror::DoubleArray>()));
 | |
|   const bool native_byte_order = false;
 | |
|   Handle<mirror::ByteBufferViewVarHandle> vh(hs.NewHandle(
 | |
|       CreateByteBufferViewVarHandle(self, double_array_class, native_byte_order, mask)));
 | |
|   EXPECT_FALSE(vh.IsNull());
 | |
|   EXPECT_EQ(native_byte_order, vh->GetNativeByteOrder());
 | |
| 
 | |
|   // Check access modes
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetVolatile));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetVolatile));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetOpaque));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kSetOpaque));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndSet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchange));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kCompareAndExchangeRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetPlain));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSet));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kWeakCompareAndSetRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSet));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndSetRelease));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAdd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndAddRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOr));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseOrAcquire));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAnd));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndRelease));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseAndAcquire));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXor));
 | |
|   EXPECT_FALSE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorRelease));
 | |
|   EXPECT_TRUE(vh->IsAccessModeSupported(VarHandle::AccessMode::kGetAndBitwiseXorAcquire));
 | |
| 
 | |
|   // Check compatibility - "Get" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)D"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;D)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)Z"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "Set" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndSet" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndSet;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDI)D"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;I)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Z)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "CompareAndExchange" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kCompareAndExchange;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)D"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;IDD)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;II)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(III)V"));
 | |
|   }
 | |
| 
 | |
|   // Check compatibility - "GetAndUpdate" pattern
 | |
|   {
 | |
|     const VarHandle::AccessMode access_mode = VarHandle::AccessMode::kGetAndAdd;
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)D"));
 | |
|     EXPECT_TRUE(AccessModeExactMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)V"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(Ljava/nio/ByteBuffer;ID)Z"));
 | |
|     EXPECT_TRUE(AccessModeNoMatch(vh, access_mode, "(II)V"));
 | |
|   }
 | |
| 
 | |
|   // Check synthesized method types match expected forms.
 | |
|   {
 | |
|     Handle<MethodType> get = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;I)D"));
 | |
|     Handle<MethodType> set = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;ID)V"));
 | |
|     Handle<MethodType> compareAndSet = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)Z"));
 | |
|     Handle<MethodType> compareAndExchange =
 | |
|         hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)D"));
 | |
|     Handle<MethodType> getAndUpdate = hs.NewHandle(MethodTypeOf("(Ljava/nio/ByteBuffer;ID)D"));
 | |
|     auto test_mode = [=](VarHandle::AccessMode access_mode, Handle<MethodType> method_type)
 | |
|         REQUIRES_SHARED(Locks::mutator_lock_) {
 | |
|       return vh->GetMethodTypeForAccessMode(self, access_mode)->IsExactMatch(method_type.Get());
 | |
|     };
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGet, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSet, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetVolatile, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetVolatile, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAcquire, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetRelease, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetOpaque, get));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kSetOpaque, set));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchange, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeAcquire, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kCompareAndExchangeRelease, compareAndExchange));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetPlain, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSet, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetAcquire, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kWeakCompareAndSetRelease, compareAndSet));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSet, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndSetRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAdd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndAddRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOr, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAnd, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXor, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorRelease, getAndUpdate));
 | |
|     EXPECT_TRUE(test_mode(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, getAndUpdate));
 | |
|   }
 | |
| }
 | |
| 
 | |
| TEST_F(VarHandleTest, GetMethodTypeForAccessMode) {
 | |
|   VarHandle::AccessMode access_mode;
 | |
| 
 | |
|   // Invalid access mode names
 | |
|   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName(nullptr, &access_mode));
 | |
|   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("", &access_mode));
 | |
|   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("CompareAndExchange", &access_mode));
 | |
|   EXPECT_FALSE(VarHandle::GetAccessModeByMethodName("compareAndExchangX", &access_mode));
 | |
| 
 | |
|   // Valid access mode names
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchange", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchange, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchangeAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchangeAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndExchangeRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kCompareAndExchangeRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("compareAndSet", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kCompareAndSet, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("get", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGet, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAdd", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndAdd, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAddAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndAddAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndAddRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndAddRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAnd", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAnd, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAndAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAndAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseAndRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseAndRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOr", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOr, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOrAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOrAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseOrRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseOrRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXor", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXor, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXorAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXorAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndBitwiseXorRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndBitwiseXorRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSet", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndSet, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSetAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndSetAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getAndSetRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetAndSetRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getOpaque", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetOpaque, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("getVolatile", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kGetVolatile, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("set", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kSet, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setOpaque", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kSetOpaque, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kSetRelease, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("setVolatile", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kSetVolatile, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSet", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSet, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetAcquire", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetAcquire, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetPlain", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetPlain, access_mode);
 | |
|   EXPECT_TRUE(VarHandle::GetAccessModeByMethodName("weakCompareAndSetRelease", &access_mode));
 | |
|   EXPECT_EQ(VarHandle::AccessMode::kWeakCompareAndSetRelease, access_mode);
 | |
| }
 | |
| 
 | |
| }  // namespace mirror
 | |
| }  // namespace art
 |