diff options
author | 2019-03-25 15:55:42 +0000 | |
---|---|---|
committer | 2019-03-26 09:52:25 +0000 | |
commit | f57f2ed8c3f75c8d8c2c051f2961ca4e8330a698 (patch) | |
tree | 8a734652280d099f95d0d2f8cb358fcf56ca0d47 | |
parent | 5cb98a99cff06cd6a5b94f7d819b180d6e621f32 (diff) |
ART: Clean up obj_ptr.h and obj_ptr-inl.h .
Move ObjPtr<> member function definitions that depend on
other functions in obj_ptr-inl.h also to the obj_ptr-inl.h.
Use C++14 std::enable_if_t<> and C++17 std::is_base_of_v<>.
Improve kObjPtrPoisoningValidateOnCopy code readability
(avoid ternary operator). Move relational opeators to
namespace scope and reimplement != as negation of ==.
Also move PtrCompression<>::Compress(ObjPtr<>) to the
object_reference-inl.h which includes obj_ptr-inl.h.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I5116c0e322775c19a88687f30742ef654a8be873
-rw-r--r-- | runtime/mirror/object_reference-inl.h | 5 | ||||
-rw-r--r-- | runtime/mirror/object_reference.h | 4 | ||||
-rw-r--r-- | runtime/obj_ptr-inl.h | 115 | ||||
-rw-r--r-- | runtime/obj_ptr.h | 148 |
4 files changed, 181 insertions, 91 deletions
diff --git a/runtime/mirror/object_reference-inl.h b/runtime/mirror/object_reference-inl.h index 780d6621ae..183a5af201 100644 --- a/runtime/mirror/object_reference-inl.h +++ b/runtime/mirror/object_reference-inl.h @@ -24,6 +24,11 @@ namespace art { namespace mirror { +template<bool kPoisonReferences, class MirrorType> +inline uint32_t PtrCompression<kPoisonReferences, MirrorType>::Compress(ObjPtr<MirrorType> ptr) { + return Compress(ptr.Ptr()); +} + template <bool kPoisonReferences, class MirrorType> ALWAYS_INLINE void ObjectReference<kPoisonReferences, MirrorType>::Assign(ObjPtr<MirrorType> ptr) { diff --git a/runtime/mirror/object_reference.h b/runtime/mirror/object_reference.h index e19e1656ee..f01bcbd83a 100644 --- a/runtime/mirror/object_reference.h +++ b/runtime/mirror/object_reference.h @@ -48,9 +48,7 @@ class PtrCompression { } // Convert an ObjPtr to a compressed reference. - static uint32_t Compress(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_) { - return Compress(ptr.Ptr()); - } + static uint32_t Compress(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_); }; // Value type representing a reference to a mirror::Object of type MirrorType. diff --git a/runtime/obj_ptr-inl.h b/runtime/obj_ptr-inl.h index f096445913..3eb5b15e2e 100644 --- a/runtime/obj_ptr-inl.h +++ b/runtime/obj_ptr-inl.h @@ -64,6 +64,121 @@ inline uintptr_t ObjPtr<MirrorType>::Encode(MirrorType* ptr) { } template<class MirrorType> +template <typename Type, + typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */> +inline ObjPtr<MirrorType>::ObjPtr(Type* ptr) + : reference_(Encode(static_cast<MirrorType*>(ptr))) { +} + +template<class MirrorType> +template <typename Type, + typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */> +inline ObjPtr<MirrorType>::ObjPtr(const ObjPtr<Type>& other) + : reference_(other.reference_) { + if (kObjPtrPoisoningValidateOnCopy) { + AssertValid(); + } +} + +template<class MirrorType> +template <typename Type, + typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */> +inline ObjPtr<MirrorType>& ObjPtr<MirrorType>::operator=(const ObjPtr<Type>& other) { + reference_ = other.reference_; + if (kObjPtrPoisoningValidateOnCopy) { + AssertValid(); + } + return *this; +} + +template<class MirrorType> +OBJPTR_INLINE ObjPtr<MirrorType>& ObjPtr<MirrorType>::operator=(MirrorType* ptr) { + Assign(ptr); + return *this; +} + +template<class MirrorType> +inline void ObjPtr<MirrorType>::Assign(MirrorType* ptr) { + reference_ = Encode(ptr); +} + +template<class MirrorType> +inline MirrorType* ObjPtr<MirrorType>::operator->() const { + return Ptr(); +} + +template<class MirrorType> +inline MirrorType* ObjPtr<MirrorType>::Ptr() const { + AssertValid(); + return PtrUnchecked(); +} + +template<class MirrorType> +template <typename SourceType> +inline ObjPtr<MirrorType> ObjPtr<MirrorType>::DownCast(ObjPtr<SourceType> ptr) { + static_assert(std::is_base_of_v<SourceType, MirrorType>, + "Target type must be a subtype of source type"); + return static_cast<MirrorType*>(ptr.Ptr()); +} + +template<class MirrorType> +size_t HashObjPtr::operator()(const ObjPtr<MirrorType>& ptr) const { + return std::hash<MirrorType*>()(ptr.Ptr()); +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return lhs.Ptr() == rhs.Ptr(); +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return lhs == rhs.Ptr(); +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return lhs.Ptr() == rhs; +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return !(lhs == rhs); +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return !(lhs == rhs); +} + +template<class MirrorType1, class MirrorType2> +inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) REQUIRES_SHARED(Locks::mutator_lock_) { + return !(lhs == rhs); +} + +template<class MirrorType> +static inline ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr) { + return ObjPtr<MirrorType>(ptr); +} + +template<class MirrorType> +static inline ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr) { + return ObjPtr<MirrorType>(ptr); +} + +template<class MirrorType> inline std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType> ptr) { // May be used for dumping bad pointers, do not use the checked version. return os << ptr.PtrUnchecked(); diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h index b0f24dabc8..1f79d37516 100644 --- a/runtime/obj_ptr.h +++ b/runtime/obj_ptr.h @@ -59,86 +59,34 @@ class ObjPtr { : reference_(0u) {} template <typename Type, - typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type> - OBJPTR_INLINE ObjPtr(Type* ptr) - REQUIRES_SHARED(Locks::mutator_lock_) - : reference_(Encode(static_cast<MirrorType*>(ptr))) { - } + typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>> + OBJPTR_INLINE ObjPtr(Type* ptr) REQUIRES_SHARED(Locks::mutator_lock_); template <typename Type, - typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type> - OBJPTR_INLINE ObjPtr(const ObjPtr<Type>& other) - REQUIRES_SHARED(Locks::mutator_lock_) - : reference_(kObjPtrPoisoningValidateOnCopy - ? Encode(static_cast<MirrorType*>(other.Ptr())) - : other.reference_) { - } + typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>> + OBJPTR_INLINE ObjPtr(const ObjPtr<Type>& other) REQUIRES_SHARED(Locks::mutator_lock_); template <typename Type, - typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type> - OBJPTR_INLINE ObjPtr& operator=(const ObjPtr<Type>& other) - REQUIRES_SHARED(Locks::mutator_lock_) { - reference_ = kObjPtrPoisoningValidateOnCopy - ? Encode(static_cast<MirrorType*>(other.Ptr())) - : other.reference_; - return *this; - } + typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>> + OBJPTR_INLINE ObjPtr& operator=(const ObjPtr<Type>& other) REQUIRES_SHARED(Locks::mutator_lock_); - OBJPTR_INLINE ObjPtr& operator=(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_) { - Assign(ptr); - return *this; - } + OBJPTR_INLINE ObjPtr& operator=(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_); - OBJPTR_INLINE void Assign(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_) { - reference_ = Encode(ptr); - } + OBJPTR_INLINE void Assign(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_); - OBJPTR_INLINE MirrorType* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) { - return Ptr(); - } + OBJPTR_INLINE MirrorType* operator->() const REQUIRES_SHARED(Locks::mutator_lock_); OBJPTR_INLINE bool IsNull() const { return reference_ == 0; } // Ptr makes sure that the object pointer is valid. - OBJPTR_INLINE MirrorType* Ptr() const REQUIRES_SHARED(Locks::mutator_lock_) { - AssertValid(); - return PtrUnchecked(); - } + OBJPTR_INLINE MirrorType* Ptr() const REQUIRES_SHARED(Locks::mutator_lock_); OBJPTR_INLINE bool IsValid() const REQUIRES_SHARED(Locks::mutator_lock_); OBJPTR_INLINE void AssertValid() const REQUIRES_SHARED(Locks::mutator_lock_); - OBJPTR_INLINE bool operator==(const ObjPtr& ptr) const REQUIRES_SHARED(Locks::mutator_lock_) { - return Ptr() == ptr.Ptr(); - } - - template <typename PointerType> - OBJPTR_INLINE bool operator==(const PointerType* ptr) const - REQUIRES_SHARED(Locks::mutator_lock_) { - return Ptr() == ptr; - } - - OBJPTR_INLINE bool operator==(std::nullptr_t) const { - return IsNull(); - } - - OBJPTR_INLINE bool operator!=(const ObjPtr& ptr) const REQUIRES_SHARED(Locks::mutator_lock_) { - return Ptr() != ptr.Ptr(); - } - - template <typename PointerType> - OBJPTR_INLINE bool operator!=(const PointerType* ptr) const - REQUIRES_SHARED(Locks::mutator_lock_) { - return Ptr() != ptr; - } - - OBJPTR_INLINE bool operator!=(std::nullptr_t) const { - return !IsNull(); - } - // Ptr unchecked does not check that object pointer is valid. Do not use if you can avoid it. OBJPTR_INLINE MirrorType* PtrUnchecked() const { if (kObjPtrPoisoning) { @@ -151,11 +99,7 @@ class ObjPtr { // Static function to be friendly with null pointers. template <typename SourceType> - static ObjPtr<MirrorType> DownCast(ObjPtr<SourceType> ptr) REQUIRES_SHARED(Locks::mutator_lock_) { - static_assert(std::is_base_of<SourceType, MirrorType>::value, - "Target type must be a subtype of source type"); - return static_cast<MirrorType*>(ptr.Ptr()); - } + static ObjPtr<MirrorType> DownCast(ObjPtr<SourceType> ptr) REQUIRES_SHARED(Locks::mutator_lock_); private: // Trim off high bits of thread local cookie. @@ -179,42 +123,70 @@ static_assert(std::is_trivially_copyable<ObjPtr<void>>::value, class HashObjPtr { public: template<class MirrorType> - size_t operator()(const ObjPtr<MirrorType>& ptr) const NO_THREAD_SAFETY_ANALYSIS { - return std::hash<MirrorType*>()(ptr.Ptr()); - } + size_t operator()(const ObjPtr<MirrorType>& ptr) const NO_THREAD_SAFETY_ANALYSIS; }; -template<class MirrorType, typename PointerType> -OBJPTR_INLINE bool operator==(const PointerType* a, const ObjPtr<MirrorType>& b) - REQUIRES_SHARED(Locks::mutator_lock_) { - return b == a; -} +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) + REQUIRES_SHARED(Locks::mutator_lock_); + +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) + REQUIRES_SHARED(Locks::mutator_lock_); + +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator==(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) + REQUIRES_SHARED(Locks::mutator_lock_); template<class MirrorType> -OBJPTR_INLINE bool operator==(std::nullptr_t, const ObjPtr<MirrorType>& b) { - return b == nullptr; +OBJPTR_INLINE bool operator==(ObjPtr<MirrorType> ptr, std::nullptr_t) { + return ptr.IsNull(); } -template<typename MirrorType, typename PointerType> -OBJPTR_INLINE bool operator!=(const PointerType* a, const ObjPtr<MirrorType>& b) - REQUIRES_SHARED(Locks::mutator_lock_) { - return b != a; +template<class MirrorType> +OBJPTR_INLINE bool operator==(std::nullptr_t, ObjPtr<MirrorType> ptr) { + return ptr.IsNull(); } +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) + REQUIRES_SHARED(Locks::mutator_lock_); + +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) + REQUIRES_SHARED(Locks::mutator_lock_); + +template<class MirrorType1, class MirrorType2> +OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> || + std::is_base_of_v<MirrorType2, MirrorType1>, bool> +operator!=(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) + REQUIRES_SHARED(Locks::mutator_lock_); + template<class MirrorType> -OBJPTR_INLINE bool operator!=(std::nullptr_t, const ObjPtr<MirrorType>& b) { - return b != nullptr; +OBJPTR_INLINE bool operator!=(ObjPtr<MirrorType> ptr, std::nullptr_t) { + return !(ptr == nullptr); } template<class MirrorType> -static inline ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr) { - return ObjPtr<MirrorType>(ptr); +OBJPTR_INLINE bool operator!=(std::nullptr_t, ObjPtr<MirrorType> ptr) { + return !(nullptr == ptr); } template<class MirrorType> -static inline ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr) { - return ObjPtr<MirrorType>(ptr); -} +static OBJPTR_INLINE ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr); + +template<class MirrorType> +static OBJPTR_INLINE ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr); template<class MirrorType> OBJPTR_INLINE std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType> ptr); |