diff options
author | 2019-03-27 11:00:36 +0000 | |
---|---|---|
committer | 2019-03-28 09:22:07 +0000 | |
commit | 5aead700219d9c9fc05524d5d72dc32cb1807c61 (patch) | |
tree | 84dac95f7627fefc8fd8d3dfbd5d6baf5d1e1a01 | |
parent | 4f1e3288a845b91a5ce369865ec7e249f4f94622 (diff) |
ObjPtr<>-ify method/var handles, fix stale refs in tests.
Test: m test-art-host-gtest
Test: testrunner.py --host --interpreter
Bug: 31113334
Change-Id: I89ea84f7970899643e437161b598d3232a182e98
-rw-r--r-- | runtime/class_linker.cc | 4 | ||||
-rw-r--r-- | runtime/class_linker.h | 16 | ||||
-rw-r--r-- | runtime/class_linker_test.cc | 2 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 1 | ||||
-rw-r--r-- | runtime/method_handles-inl.h | 2 | ||||
-rw-r--r-- | runtime/method_handles.cc | 2 | ||||
-rw-r--r-- | runtime/method_handles_test.cc | 4 | ||||
-rw-r--r-- | runtime/mirror/emulated_stack_frame.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/method_handle_impl-inl.h | 4 | ||||
-rw-r--r-- | runtime/mirror/method_handle_impl.cc | 8 | ||||
-rw-r--r-- | runtime/mirror/method_handle_impl.h | 13 | ||||
-rw-r--r-- | runtime/mirror/method_handles_lookup.cc | 17 | ||||
-rw-r--r-- | runtime/mirror/method_handles_lookup.h | 11 | ||||
-rw-r--r-- | runtime/mirror/method_type-inl.h | 42 | ||||
-rw-r--r-- | runtime/mirror/method_type.cc | 39 | ||||
-rw-r--r-- | runtime/mirror/method_type.h | 34 | ||||
-rw-r--r-- | runtime/mirror/method_type_test.cc | 4 | ||||
-rw-r--r-- | runtime/mirror/var_handle.cc | 6 | ||||
-rw-r--r-- | runtime/mirror/var_handle.h | 4 | ||||
-rw-r--r-- | runtime/mirror/var_handle_test.cc | 460 | ||||
-rw-r--r-- | runtime/var_handles.cc | 2 |
21 files changed, 363 insertions, 314 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 6837c7fb38..97234afc50 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -8819,7 +8819,7 @@ ObjPtr<mirror::MethodType> ClassLinker::ResolveMethodType(Thread* self, return ResolveMethodType(self, proto_idx, dex_cache, class_loader); } -mirror::MethodHandle* ClassLinker::ResolveMethodHandleForField( +ObjPtr<mirror::MethodHandle> ClassLinker::ResolveMethodHandleForField( Thread* self, const dex::MethodHandleItem& method_handle, ArtMethod* referrer) { @@ -8947,7 +8947,7 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForField( return mirror::MethodHandleImpl::Create(self, target, kind, method_type); } -mirror::MethodHandle* ClassLinker::ResolveMethodHandleForMethod( +ObjPtr<mirror::MethodHandle> ClassLinker::ResolveMethodHandleForMethod( Thread* self, const dex::MethodHandleItem& method_handle, ArtMethod* referrer) { diff --git a/runtime/class_linker.h b/runtime/class_linker.h index b4d8833515..5c3e620969 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -1034,15 +1034,15 @@ class ClassLinker { ArtMethod** out_imt) REQUIRES_SHARED(Locks::mutator_lock_); - mirror::MethodHandle* ResolveMethodHandleForField(Thread* self, - const dex::MethodHandleItem& method_handle, - ArtMethod* referrer) - REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::MethodHandle> ResolveMethodHandleForField( + Thread* self, + const dex::MethodHandleItem& method_handle, + ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_); - mirror::MethodHandle* ResolveMethodHandleForMethod(Thread* self, - const dex::MethodHandleItem& method_handle, - ArtMethod* referrer) - REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::MethodHandle> ResolveMethodHandleForMethod( + Thread* self, + const dex::MethodHandleItem& method_handle, + ArtMethod* referrer) REQUIRES_SHARED(Locks::mutator_lock_); // A wrapper class representing the result of a method translation used for linking methods and // updating superclass default methods. For each method in a classes vtable there are 4 states it diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 91cea796b3..c969051459 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -46,7 +46,7 @@ #include "mirror/field.h" #include "mirror/method_handle_impl.h" #include "mirror/method_handles_lookup.h" -#include "mirror/method_type.h" +#include "mirror/method_type-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-alloc-inl.h" #include "mirror/object_array-inl.h" diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index db3032a908..d33062da22 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -34,6 +34,7 @@ #include "mirror/class.h" #include "mirror/emulated_stack_frame.h" #include "mirror/method_handle_impl-inl.h" +#include "mirror/method_type-inl.h" #include "mirror/object_array-alloc-inl.h" #include "mirror/object_array-inl.h" #include "mirror/var_handle.h" diff --git a/runtime/method_handles-inl.h b/runtime/method_handles-inl.h index c4ac982576..4bd4df10d2 100644 --- a/runtime/method_handles-inl.h +++ b/runtime/method_handles-inl.h @@ -25,7 +25,7 @@ #include "interpreter/shadow_frame-inl.h" #include "jvalue-inl.h" #include "mirror/class.h" -#include "mirror/method_type.h" +#include "mirror/method_type-inl.h" #include "mirror/object.h" #include "reflection.h" #include "stack.h" diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index aeeb05b62c..dac68fa584 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -25,7 +25,7 @@ #include "mirror/class-inl.h" #include "mirror/emulated_stack_frame-inl.h" #include "mirror/method_handle_impl-inl.h" -#include "mirror/method_type.h" +#include "mirror/method_type-inl.h" #include "mirror/var_handle.h" #include "reflection-inl.h" #include "reflection.h" diff --git a/runtime/method_handles_test.cc b/runtime/method_handles_test.cc index 6a7eb8c8e1..688febc4b5 100644 --- a/runtime/method_handles_test.cc +++ b/runtime/method_handles_test.cc @@ -46,8 +46,8 @@ namespace { return throwable->GetClass()->DescriptorEquals("Ljava/lang/invoke/WrongMethodTypeException;"); } - static mirror::MethodType* CreateVoidMethodType(Thread* self, - Handle<mirror::Class> parameter_type) + static ObjPtr<mirror::MethodType> CreateVoidMethodType(Thread* self, + Handle<mirror::Class> parameter_type) REQUIRES_SHARED(Locks::mutator_lock_) { ClassLinker* cl = Runtime::Current()->GetClassLinker(); StackHandleScope<2> hs(self); diff --git a/runtime/mirror/emulated_stack_frame.cc b/runtime/mirror/emulated_stack_frame.cc index 6ae577c120..f341788985 100644 --- a/runtime/mirror/emulated_stack_frame.cc +++ b/runtime/mirror/emulated_stack_frame.cc @@ -24,7 +24,7 @@ #include "jvalue-inl.h" #include "method_handles-inl.h" #include "method_handles.h" -#include "method_type.h" +#include "method_type-inl.h" #include "object_array-alloc-inl.h" #include "object_array-inl.h" #include "reflection-inl.h" diff --git a/runtime/mirror/method_handle_impl-inl.h b/runtime/mirror/method_handle_impl-inl.h index 0840d16c38..12047d4efa 100644 --- a/runtime/mirror/method_handle_impl-inl.h +++ b/runtime/mirror/method_handle_impl-inl.h @@ -25,11 +25,11 @@ namespace art { namespace mirror { -inline mirror::MethodType* MethodHandle::GetMethodType() { +inline ObjPtr<mirror::MethodType> MethodHandle::GetMethodType() { return GetFieldObject<mirror::MethodType>(OFFSET_OF_OBJECT_MEMBER(MethodHandle, method_type_)); } -inline mirror::MethodType* MethodHandle::GetNominalType() { +inline ObjPtr<mirror::MethodType> MethodHandle::GetNominalType() { return GetFieldObject<mirror::MethodType>(OFFSET_OF_OBJECT_MEMBER(MethodHandle, nominal_type_)); } diff --git a/runtime/mirror/method_handle_impl.cc b/runtime/mirror/method_handle_impl.cc index e8cacd97df..433d4ba532 100644 --- a/runtime/mirror/method_handle_impl.cc +++ b/runtime/mirror/method_handle_impl.cc @@ -42,10 +42,10 @@ void MethodHandle::Initialize(uintptr_t art_field_or_method, SetField64<false>(ArtFieldOrMethodOffset(), art_field_or_method); } -mirror::MethodHandleImpl* MethodHandleImpl::Create(Thread* const self, - uintptr_t art_field_or_method, - MethodHandle::Kind kind, - Handle<MethodType> method_type) +ObjPtr<mirror::MethodHandleImpl> MethodHandleImpl::Create(Thread* const self, + uintptr_t art_field_or_method, + MethodHandle::Kind kind, + Handle<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) { StackHandleScope<1> hs(self); Handle<mirror::MethodHandleImpl> mh(hs.NewHandle(ObjPtr<MethodHandleImpl>::DownCast( diff --git a/runtime/mirror/method_handle_impl.h b/runtime/mirror/method_handle_impl.h index 030a49ed1e..c973a24111 100644 --- a/runtime/mirror/method_handle_impl.h +++ b/runtime/mirror/method_handle_impl.h @@ -21,6 +21,7 @@ #include "art_method.h" #include "class.h" #include "method_type.h" +#include "obj_ptr.h" #include "object.h" namespace art { @@ -66,9 +67,9 @@ class MANAGED MethodHandle : public Object { return static_cast<Kind>(handle_kind); } - ALWAYS_INLINE mirror::MethodType* GetMethodType() REQUIRES_SHARED(Locks::mutator_lock_); + ALWAYS_INLINE ObjPtr<mirror::MethodType> GetMethodType() REQUIRES_SHARED(Locks::mutator_lock_); - ALWAYS_INLINE mirror::MethodType* GetNominalType() REQUIRES_SHARED(Locks::mutator_lock_); + ALWAYS_INLINE ObjPtr<mirror::MethodType> GetNominalType() REQUIRES_SHARED(Locks::mutator_lock_); ArtField* GetTargetField() REQUIRES_SHARED(Locks::mutator_lock_) { return reinterpret_cast<ArtField*>( @@ -121,10 +122,10 @@ class MANAGED MethodHandle : public Object { // C++ mirror of java.lang.invoke.MethodHandleImpl class MANAGED MethodHandleImpl : public MethodHandle { public: - static mirror::MethodHandleImpl* Create(Thread* const self, - uintptr_t art_field_or_method, - MethodHandle::Kind kind, - Handle<MethodType> method_type) + static ObjPtr<mirror::MethodHandleImpl> Create(Thread* const self, + uintptr_t art_field_or_method, + MethodHandle::Kind kind, + Handle<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); private: diff --git a/runtime/mirror/method_handles_lookup.cc b/runtime/mirror/method_handles_lookup.cc index de17c8d056..a32fe333a7 100644 --- a/runtime/mirror/method_handles_lookup.cc +++ b/runtime/mirror/method_handles_lookup.cc @@ -22,13 +22,14 @@ #include "handle_scope.h" #include "jni/jni_internal.h" #include "mirror/method_handle_impl.h" +#include "obj_ptr-inl.h" #include "object-inl.h" #include "well_known_classes.h" namespace art { namespace mirror { -MethodHandlesLookup* MethodHandlesLookup::Create(Thread* const self, Handle<Class> lookup_class) +ObjPtr<MethodHandlesLookup> MethodHandlesLookup::Create(Thread* const self, Handle<Class> lookup_class) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) { static constexpr uint32_t kAllModes = kAccPublic | kAccPrivate | kAccProtected | kAccStatic; @@ -36,19 +37,19 @@ MethodHandlesLookup* MethodHandlesLookup::Create(Thread* const self, Handle<Clas GetClassRoot<MethodHandlesLookup>()->AllocObject(self)); mhl->SetFieldObject<false>(LookupClassOffset(), lookup_class.Get()); mhl->SetField32<false>(AllowedModesOffset(), kAllModes); - return mhl.Ptr(); + return mhl; } -MethodHandlesLookup* MethodHandlesLookup::GetDefault(Thread* const self) { +ObjPtr<MethodHandlesLookup> MethodHandlesLookup::GetDefault(Thread* const self) { ArtMethod* lookup = jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandles_lookup); JValue result; lookup->Invoke(self, nullptr, 0, &result, "L"); - return down_cast<MethodHandlesLookup*>(result.GetL()); + return ObjPtr<MethodHandlesLookup>::DownCast(MakeObjPtr(result.GetL())); } -MethodHandle* MethodHandlesLookup::FindConstructor(Thread* const self, - Handle<Class> klass, - Handle<MethodType> method_type) { +ObjPtr<MethodHandle> MethodHandlesLookup::FindConstructor(Thread* const self, + Handle<Class> klass, + Handle<MethodType> method_type) { ArtMethod* findConstructor = jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor); uint32_t args[] = { @@ -58,7 +59,7 @@ MethodHandle* MethodHandlesLookup::FindConstructor(Thread* const self, }; JValue result; findConstructor->Invoke(self, args, sizeof(args), &result, "LLL"); - return down_cast<MethodHandle*>(result.GetL()); + return ObjPtr<MethodHandle>::DownCast(MakeObjPtr(result.GetL())); } } // namespace mirror diff --git a/runtime/mirror/method_handles_lookup.h b/runtime/mirror/method_handles_lookup.h index 56261eca67..d4dbf8308a 100644 --- a/runtime/mirror/method_handles_lookup.h +++ b/runtime/mirror/method_handles_lookup.h @@ -35,18 +35,17 @@ class MethodType; // C++ mirror of java.lang.invoke.MethodHandles.Lookup class MANAGED MethodHandlesLookup : public Object { public: - static mirror::MethodHandlesLookup* Create(Thread* const self, - Handle<Class> lookup_class) + static ObjPtr<mirror::MethodHandlesLookup> Create(Thread* const self, Handle<Class> lookup_class) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); // Returns the result of java.lang.invoke.MethodHandles.lookup(). - static mirror::MethodHandlesLookup* GetDefault(Thread* const self) + static ObjPtr<mirror::MethodHandlesLookup> GetDefault(Thread* const self) REQUIRES_SHARED(Locks::mutator_lock_); // Find constructor using java.lang.invoke.MethodHandles$Lookup.findConstructor(). - mirror::MethodHandle* FindConstructor(Thread* const self, - Handle<Class> klass, - Handle<MethodType> method_type) + ObjPtr<mirror::MethodHandle> FindConstructor(Thread* const self, + Handle<Class> klass, + Handle<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_); private: diff --git a/runtime/mirror/method_type-inl.h b/runtime/mirror/method_type-inl.h new file mode 100644 index 0000000000..86b8099f19 --- /dev/null +++ b/runtime/mirror/method_type-inl.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 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. + */ + +#ifndef ART_RUNTIME_MIRROR_METHOD_TYPE_INL_H_ +#define ART_RUNTIME_MIRROR_METHOD_TYPE_INL_H_ + +#include "method_type.h" + +#include "mirror/object-inl.h" + +namespace art { +namespace mirror { + +inline ObjPtr<ObjectArray<Class>> MethodType::GetPTypes() { + return GetFieldObject<ObjectArray<Class>>(OFFSET_OF_OBJECT_MEMBER(MethodType, p_types_)); +} + +inline int MethodType::GetNumberOfPTypes() { + return GetPTypes()->GetLength(); +} + +inline ObjPtr<Class> MethodType::GetRType() { + return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(MethodType, r_type_)); +} + +} // namespace mirror +} // namespace art + +#endif // ART_RUNTIME_MIRROR_METHOD_TYPE_INL_H_ diff --git a/runtime/mirror/method_type.cc b/runtime/mirror/method_type.cc index 11d7756967..005bb710eb 100644 --- a/runtime/mirror/method_type.cc +++ b/runtime/mirror/method_type.cc @@ -14,11 +14,12 @@ * limitations under the License. */ -#include "method_type.h" +#include "method_type-inl.h" #include "class-alloc-inl.h" #include "class_root.h" #include "method_handles.h" +#include "obj_ptr-inl.h" #include "object_array-alloc-inl.h" #include "object_array-inl.h" @@ -35,9 +36,9 @@ ObjPtr<ObjectArray<Class>> AllocatePTypesArray(Thread* self, int count) } // namespace -MethodType* MethodType::Create(Thread* const self, - Handle<Class> return_type, - Handle<ObjectArray<Class>> parameter_types) { +ObjPtr<MethodType> MethodType::Create(Thread* const self, + Handle<Class> return_type, + Handle<ObjectArray<Class>> parameter_types) { StackHandleScope<1> hs(self); Handle<MethodType> mt( hs.NewHandle(ObjPtr<MethodType>::DownCast(GetClassRoot<MethodType>()->AllocObject(self)))); @@ -54,8 +55,8 @@ MethodType* MethodType::Create(Thread* const self, return mt.Get(); } -MethodType* MethodType::CloneWithoutLeadingParameter(Thread* const self, - ObjPtr<MethodType> method_type) { +ObjPtr<MethodType> MethodType::CloneWithoutLeadingParameter(Thread* const self, + ObjPtr<MethodType> method_type) { StackHandleScope<3> hs(self); Handle<ObjectArray<Class>> src_ptypes = hs.NewHandle(method_type->GetPTypes()); Handle<Class> dst_rtype = hs.NewHandle(method_type->GetRType()); @@ -70,13 +71,13 @@ MethodType* MethodType::CloneWithoutLeadingParameter(Thread* const self, return Create(self, dst_rtype, dst_ptypes); } -MethodType* MethodType::CollectTrailingArguments(Thread* self, - ObjPtr<MethodType> method_type, - ObjPtr<Class> collector_array_class, - int32_t start_index) { +ObjPtr<MethodType> MethodType::CollectTrailingArguments(Thread* self, + ObjPtr<MethodType> method_type, + ObjPtr<Class> collector_array_class, + int32_t start_index) { int32_t ptypes_length = method_type->GetNumberOfPTypes(); if (start_index > ptypes_length) { - return method_type.Ptr(); + return method_type; } StackHandleScope<4> hs(self); @@ -95,7 +96,7 @@ MethodType* MethodType::CollectTrailingArguments(Thread* self, } size_t MethodType::NumberOfVRegs() REQUIRES_SHARED(Locks::mutator_lock_) { - ObjectArray<Class>* const p_types = GetPTypes(); + ObjPtr<ObjectArray<Class>> const p_types = GetPTypes(); const int32_t p_types_length = p_types->GetLength(); // Initialize |num_vregs| with number of parameters and only increment it for @@ -110,11 +111,11 @@ size_t MethodType::NumberOfVRegs() REQUIRES_SHARED(Locks::mutator_lock_) { return num_vregs; } -bool MethodType::IsExactMatch(MethodType* target) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjectArray<Class>* const p_types = GetPTypes(); +bool MethodType::IsExactMatch(ObjPtr<MethodType> target) { + ObjPtr<ObjectArray<Class>> const p_types = GetPTypes(); const int32_t params_length = p_types->GetLength(); - ObjectArray<Class>* const target_p_types = target->GetPTypes(); + ObjPtr<ObjectArray<Class>> const target_p_types = target->GetPTypes(); if (params_length != target_p_types->GetLength()) { return false; } @@ -126,11 +127,11 @@ bool MethodType::IsExactMatch(MethodType* target) REQUIRES_SHARED(Locks::mutator return GetRType() == target->GetRType(); } -bool MethodType::IsConvertible(MethodType* target) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjectArray<Class>* const p_types = GetPTypes(); +bool MethodType::IsConvertible(ObjPtr<MethodType> target) { + ObjPtr<ObjectArray<Class>> const p_types = GetPTypes(); const int32_t params_length = p_types->GetLength(); - ObjectArray<Class>* const target_p_types = target->GetPTypes(); + ObjPtr<ObjectArray<Class>> const target_p_types = target->GetPTypes(); if (params_length != target_p_types->GetLength()) { return false; } @@ -155,7 +156,7 @@ std::string MethodType::PrettyDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) std::ostringstream ss; ss << "("; - ObjectArray<Class>* const p_types = GetPTypes(); + ObjPtr<ObjectArray<Class>> const p_types = GetPTypes(); const int32_t params_length = p_types->GetLength(); for (int32_t i = 0; i < params_length; ++i) { ss << p_types->GetWithoutChecks(i)->PrettyDescriptor(); diff --git a/runtime/mirror/method_type.h b/runtime/mirror/method_type.h index 9cceff91cd..13edf29d8f 100644 --- a/runtime/mirror/method_type.h +++ b/runtime/mirror/method_type.h @@ -30,46 +30,40 @@ namespace mirror { // C++ mirror of java.lang.invoke.MethodType class MANAGED MethodType : public Object { public: - static MethodType* Create(Thread* const self, - Handle<Class> return_type, - Handle<ObjectArray<Class>> param_types) + static ObjPtr<MethodType> Create(Thread* const self, + Handle<Class> return_type, + Handle<ObjectArray<Class>> param_types) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - static MethodType* CloneWithoutLeadingParameter(Thread* const self, - ObjPtr<MethodType> method_type) + static ObjPtr<MethodType> CloneWithoutLeadingParameter(Thread* const self, + ObjPtr<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_); // Collects trailing parameter types into an array. Assumes caller // has checked trailing arguments are all of the same type. - static MethodType* CollectTrailingArguments(Thread* const self, - ObjPtr<MethodType> method_type, - ObjPtr<Class> collector_array_class, - int32_t start_index) + static ObjPtr<MethodType> CollectTrailingArguments(Thread* const self, + ObjPtr<MethodType> method_type, + ObjPtr<Class> collector_array_class, + int32_t start_index) REQUIRES_SHARED(Locks::mutator_lock_); - ObjectArray<Class>* GetPTypes() REQUIRES_SHARED(Locks::mutator_lock_) { - return GetFieldObject<ObjectArray<Class>>(OFFSET_OF_OBJECT_MEMBER(MethodType, p_types_)); - } + ObjPtr<ObjectArray<Class>> GetPTypes() REQUIRES_SHARED(Locks::mutator_lock_); - int GetNumberOfPTypes() REQUIRES_SHARED(Locks::mutator_lock_) { - return GetPTypes()->GetLength(); - } + int GetNumberOfPTypes() REQUIRES_SHARED(Locks::mutator_lock_); // Number of virtual registers required to hold the parameters for // this method type. size_t NumberOfVRegs() REQUIRES_SHARED(Locks::mutator_lock_); - Class* GetRType() REQUIRES_SHARED(Locks::mutator_lock_) { - return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(MethodType, r_type_)); - } + ObjPtr<Class> GetRType() REQUIRES_SHARED(Locks::mutator_lock_); // Returns true iff. |this| is an exact match for method type |target|, i.e // iff. they have the same return types and parameter types. - bool IsExactMatch(MethodType* target) REQUIRES_SHARED(Locks::mutator_lock_); + bool IsExactMatch(ObjPtr<MethodType> target) REQUIRES_SHARED(Locks::mutator_lock_); // Returns true iff. |this| can be converted to match |target| method type, i.e // iff. they have convertible return types and parameter types. - bool IsConvertible(MethodType* target) REQUIRES_SHARED(Locks::mutator_lock_); + bool IsConvertible(ObjPtr<MethodType> target) REQUIRES_SHARED(Locks::mutator_lock_); // Returns the pretty descriptor for this method type, suitable for display in // exception messages and the like. diff --git a/runtime/mirror/method_type_test.cc b/runtime/mirror/method_type_test.cc index a8411d9e10..4e9ba51655 100644 --- a/runtime/mirror/method_type_test.cc +++ b/runtime/mirror/method_type_test.cc @@ -38,8 +38,8 @@ static std::string FullyQualifiedType(const std::string& shorthand) { return "Ljava/lang/" + shorthand + ";"; } -static mirror::MethodType* CreateMethodType(const std::string& return_type, - const std::vector<std::string>& param_types) { +static ObjPtr<mirror::MethodType> CreateMethodType(const std::string& return_type, + const std::vector<std::string>& param_types) { CHECK_LT(param_types.size(), 3u); Runtime* const runtime = Runtime::Current(); diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc index 7c25529347..d887b5a114 100644 --- a/runtime/mirror/var_handle.cc +++ b/runtime/mirror/var_handle.cc @@ -26,7 +26,7 @@ #include "jni/jni_internal.h" #include "jvalue-inl.h" #include "method_handles-inl.h" -#include "method_type.h" +#include "method_type-inl.h" #include "object_array-alloc-inl.h" #include "obj_ptr-inl.h" #include "well_known_classes.h" @@ -1423,7 +1423,7 @@ int32_t VarHandle::GetAccessModesBitMask() { } VarHandle::MatchKind VarHandle::GetMethodTypeMatchForAccessMode(AccessMode access_mode, - MethodType* method_type) { + ObjPtr<MethodType> method_type) { MatchKind match = MatchKind::kExact; ObjPtr<VarHandle> vh = this; @@ -1469,7 +1469,7 @@ VarHandle::MatchKind VarHandle::GetMethodTypeMatchForAccessMode(AccessMode acces } bool VarHandle::IsInvokerMethodTypeCompatible(AccessMode access_mode, - MethodType* method_type) { + ObjPtr<MethodType> method_type) { StackHandleScope<3> hs(Thread::Current()); Handle<Class> mt_rtype(hs.NewHandle(method_type->GetRType())); Handle<VarHandle> vh(hs.NewHandle(this)); diff --git a/runtime/mirror/var_handle.h b/runtime/mirror/var_handle.h index 0cfa51c042..a46b466bb9 100644 --- a/runtime/mirror/var_handle.h +++ b/runtime/mirror/var_handle.h @@ -107,14 +107,14 @@ class MANAGED VarHandle : public Object { // Returns match information on the compatability between the exact method type for // 'access_mode' and the provided 'method_type'. - MatchKind GetMethodTypeMatchForAccessMode(AccessMode access_mode, MethodType* method_type) + MatchKind GetMethodTypeMatchForAccessMode(AccessMode access_mode, ObjPtr<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_); // Returns true if the MethodType specified is compatible with the // specified access_mode if the first parameter of method_type is // ignored. This is useful for comparing MethodType instances when // invoking a VarHandleAccessor via a MethodHandle invoker. - bool IsInvokerMethodTypeCompatible(AccessMode access_mode, MethodType* method_type) + bool IsInvokerMethodTypeCompatible(AccessMode access_mode, ObjPtr<MethodType> method_type) REQUIRES_SHARED(Locks::mutator_lock_); // Allocates and returns the MethodType associated with the diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc index 3382066043..6c765d6de1 100644 --- a/runtime/mirror/var_handle_test.cc +++ b/runtime/mirror/var_handle_test.cc @@ -40,9 +40,9 @@ namespace mirror { // Tests for mirror::VarHandle and it's descendents. class VarHandleTest : public CommonRuntimeTest { public: - static FieldVarHandle* CreateFieldVarHandle(Thread* const self, - ArtField* art_field, - int32_t access_modes_bit_mask) + 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( @@ -63,9 +63,9 @@ class VarHandleTest : public CommonRuntimeTest { return fvh.Get(); } - static ArrayElementVarHandle* CreateArrayElementVarHandle(Thread* const self, - Handle<Class> array_class, - int32_t access_modes_bit_mask) + 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( @@ -80,10 +80,11 @@ class VarHandleTest : public CommonRuntimeTest { return vh.Get(); } - static ByteArrayViewVarHandle* CreateByteArrayViewVarHandle(Thread* const self, - Handle<Class> view_array_class, - bool native_byte_order, - int32_t access_modes_bit_mask) + 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( @@ -100,10 +101,11 @@ class VarHandleTest : public CommonRuntimeTest { return bvh.Get(); } - static ByteBufferViewVarHandle* CreateByteBufferViewVarHandle(Thread* const self, - Handle<Class> view_array_class, - bool native_byte_order, - int32_t access_modes_bit_mask) + 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( @@ -131,26 +133,6 @@ class VarHandleTest : public CommonRuntimeTest { return AccessModesBitMask(first) | AccessModesBitMask(args...); } - // Helper to get the VarType of a VarHandle. - static ObjPtr<Class> GetVarType(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { - return vh->GetVarType(); - } - - // Helper to get the CoordinateType0 of a VarHandle. - static ObjPtr<Class> GetCoordinateType0(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { - return vh->GetCoordinateType0(); - } - - // Helper to get the CoordinateType1 of a VarHandle. - static ObjPtr<Class> GetCoordinateType1(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { - return vh->GetCoordinateType1(); - } - - // Helper to get the AccessModesBitMask of a VarHandle. - static int32_t GetAccessModesBitMask(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { - return vh->GetAccessModesBitMask(); - } - private: static void InitializeVarHandle(ObjPtr<VarHandle> vh, Handle<Class> var_type, @@ -183,7 +165,7 @@ class VarHandleTest : public CommonRuntimeTest { // Convenience method for constructing MethodType instances from // well-formed method descriptors. -static MethodType* MethodTypeOf(const std::string& method_descriptor) { +static ObjPtr<MethodType> MethodTypeOf(const std::string& method_descriptor) { std::vector<std::string> descriptors; auto it = method_descriptor.cbegin(); @@ -247,9 +229,9 @@ static MethodType* MethodTypeOf(const std::string& method_descriptor) { return MethodType::Create(self, rtype, ptypes); } -static bool AccessModeMatch(VarHandle* vh, +static bool AccessModeMatch(ObjPtr<VarHandle> vh, VarHandle::AccessMode access_mode, - MethodType* method_type, + ObjPtr<MethodType> method_type, VarHandle::MatchKind expected_match) REQUIRES_SHARED(Locks::mutator_lock_) { return vh->GetMethodTypeMatchForAccessMode(access_mode, method_type) == expected_match; @@ -260,9 +242,10 @@ 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, - MethodTypeOf(descriptor), + method_type, VarHandle::MatchKind::kExact); } @@ -271,9 +254,10 @@ 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, - MethodTypeOf(descriptor), + method_type, VarHandle::MatchKind::kWithConversions); } @@ -282,9 +266,10 @@ 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, - MethodTypeOf(descriptor), + method_type, VarHandle::MatchKind::kNone); } @@ -297,7 +282,7 @@ TEST_F(VarHandleTest, InstanceFieldVarHandle) { int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet, VarHandle::AccessMode::kGetAndSet, VarHandle::AccessMode::kGetAndBitwiseXor); - StackHandleScope<1> hs(self); + StackHandleScope<6> hs(self); Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask))); EXPECT_FALSE(fvh.IsNull()); EXPECT_EQ(value, fvh->GetField()); @@ -389,42 +374,46 @@ TEST_F(VarHandleTest, InstanceFieldVarHandle) { // Check synthesized method types match expected forms. { - MethodType* get = MethodTypeOf("(Ljava/lang/Integer;)I"); - MethodType* set = MethodTypeOf("(Ljava/lang/Integer;I)V"); - MethodType* compareAndSet = MethodTypeOf("(Ljava/lang/Integer;II)Z"); - MethodType* compareAndExchange = MethodTypeOf("(Ljava/lang/Integer;II)I"); - MethodType* getAndUpdate = MethodTypeOf("(Ljava/lang/Integer;I)I"); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGet)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSet)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetVolatile)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetVolatile)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAcquire)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetRelease)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetOpaque)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetOpaque)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchange)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeAcquire)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeRelease)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetPlain)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetAcquire)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetRelease)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSet)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAdd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOr)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAnd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXor)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorAcquire)->IsExactMatch(getAndUpdate)); + 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)); } } @@ -437,7 +426,7 @@ TEST_F(VarHandleTest, StaticFieldVarHandle) { int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kSet, VarHandle::AccessMode::kGetOpaque, VarHandle::AccessMode::kGetAndBitwiseAndRelease); - StackHandleScope<1> hs(self); + StackHandleScope<6> hs(self); Handle<mirror::FieldVarHandle> fvh(hs.NewHandle(CreateFieldVarHandle(self, value, mask))); EXPECT_FALSE(fvh.IsNull()); EXPECT_EQ(value, fvh->GetField()); @@ -523,49 +512,53 @@ TEST_F(VarHandleTest, StaticFieldVarHandle) { // Check synthesized method types match expected forms. { - MethodType* get = MethodTypeOf("()I"); - MethodType* set = MethodTypeOf("(I)V"); - MethodType* compareAndSet = MethodTypeOf("(II)Z"); - MethodType* compareAndExchange = MethodTypeOf("(II)I"); - MethodType* getAndUpdate = MethodTypeOf("(I)I"); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGet)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSet)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetVolatile)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetVolatile)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAcquire)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetRelease)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetOpaque)->IsExactMatch(get)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetOpaque)->IsExactMatch(set)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchange)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeAcquire)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeRelease)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetPlain)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetAcquire)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetRelease)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSet)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAdd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOr)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAnd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXor)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(fvh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorAcquire)->IsExactMatch(getAndUpdate)); + 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<2> hs(self); + StackHandleScope<7> hs(self); int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet, VarHandle::AccessMode::kSet, @@ -685,49 +678,57 @@ TEST_F(VarHandleTest, ArrayElementVarHandle) { // Check synthesized method types match expected forms. { - MethodType* get = MethodTypeOf("([Ljava/lang/String;I)Ljava/lang/String;"); - MethodType* set = MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)V"); - MethodType* compareAndSet = MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z"); - MethodType* compareAndExchange = MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - MethodType* getAndUpdate = MethodTypeOf("([Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;"); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGet)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSet)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetVolatile)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetVolatile)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAcquire)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetRelease)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetOpaque)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetOpaque)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchange)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeAcquire)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeRelease)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetPlain)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetAcquire)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetRelease)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSet)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAdd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOr)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAnd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXor)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorAcquire)->IsExactMatch(getAndUpdate)); + 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<2> hs(self); + StackHandleScope<7> hs(self); int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet, VarHandle::AccessMode::kGetVolatile, @@ -833,49 +834,53 @@ TEST_F(VarHandleTest, ByteArrayViewVarHandle) { // Check synthesized method types match expected forms. { - MethodType* get = MethodTypeOf("([BI)C"); - MethodType* set = MethodTypeOf("([BIC)V"); - MethodType* compareAndSet = MethodTypeOf("([BICC)Z"); - MethodType* compareAndExchange = MethodTypeOf("([BICC)C"); - MethodType* getAndUpdate = MethodTypeOf("([BIC)C"); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGet)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSet)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetVolatile)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetVolatile)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAcquire)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetRelease)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetOpaque)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetOpaque)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchange)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeAcquire)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeRelease)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetPlain)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetAcquire)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetRelease)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSet)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAdd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOr)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAnd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXor)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorAcquire)->IsExactMatch(getAndUpdate)); + 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<2> hs(self); + StackHandleScope<7> hs(self); int32_t mask = AccessModesBitMask(VarHandle::AccessMode::kGet, VarHandle::AccessMode::kGetVolatile, @@ -981,42 +986,47 @@ TEST_F(VarHandleTest, ByteBufferViewVarHandle) { // Check synthesized method types match expected forms. { - MethodType* get = MethodTypeOf("(Ljava/nio/ByteBuffer;I)D"); - MethodType* set = MethodTypeOf("(Ljava/nio/ByteBuffer;ID)V"); - MethodType* compareAndSet = MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)Z"); - MethodType* compareAndExchange = MethodTypeOf("(Ljava/nio/ByteBuffer;IDD)D"); - MethodType* getAndUpdate = MethodTypeOf("(Ljava/nio/ByteBuffer;ID)D"); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGet)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSet)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetVolatile)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetVolatile)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAcquire)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetRelease)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetOpaque)->IsExactMatch(get)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kSetOpaque)->IsExactMatch(set)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchange)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeAcquire)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kCompareAndExchangeRelease)->IsExactMatch(compareAndExchange)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetPlain)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSet)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetAcquire)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kWeakCompareAndSetRelease)->IsExactMatch(compareAndSet)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSet)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndSetRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAdd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndAddRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOr)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseOrAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAnd)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseAndAcquire)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXor)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorRelease)->IsExactMatch(getAndUpdate)); - EXPECT_TRUE(vh->GetMethodTypeForAccessMode(self, VarHandle::AccessMode::kGetAndBitwiseXorAcquire)->IsExactMatch(getAndUpdate)); + 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)); } } diff --git a/runtime/var_handles.cc b/runtime/var_handles.cc index f08742fcd7..73b4ddaf3a 100644 --- a/runtime/var_handles.cc +++ b/runtime/var_handles.cc @@ -20,7 +20,7 @@ #include "dex/dex_instruction.h" #include "handle.h" #include "method_handles-inl.h" -#include "mirror/method_type.h" +#include "mirror/method_type-inl.h" #include "mirror/var_handle.h" namespace art { |