| | |
| | |
| | |
| |
|
| | #ifndef INCLUDE_CPPGC_MEMBER_H_ |
| | #define INCLUDE_CPPGC_MEMBER_H_ |
| |
|
| | #include <atomic> |
| | #include <cstddef> |
| | #include <type_traits> |
| |
|
| | #include "cppgc/internal/pointer-policies.h" |
| | #include "cppgc/type-traits.h" |
| | #include "v8config.h" |
| |
|
| | namespace cppgc { |
| |
|
| | class Visitor; |
| |
|
| | namespace internal { |
| |
|
| | |
| | template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, |
| | typename CheckingPolicy> |
| | class BasicMember : private CheckingPolicy { |
| | public: |
| | using PointeeType = T; |
| |
|
| | constexpr BasicMember() = default; |
| | constexpr BasicMember(std::nullptr_t) {} |
| | BasicMember(SentinelPointer s) : raw_(s) {} |
| | BasicMember(T* raw) : raw_(raw) { |
| | InitializingWriteBarrier(); |
| | this->CheckPointer(raw_); |
| | } |
| | BasicMember(T& raw) : BasicMember(&raw) {} |
| | BasicMember(const BasicMember& other) : BasicMember(other.Get()) {} |
| | |
| | template <typename U, typename OtherBarrierPolicy, typename OtherWeaknessTag, |
| | typename OtherCheckingPolicy, |
| | typename = std::enable_if_t<std::is_base_of<T, U>::value>> |
| | BasicMember( |
| | const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, |
| | OtherCheckingPolicy>& other) |
| | : BasicMember(other.Get()) {} |
| | |
| | template <typename U, typename PersistentWeaknessPolicy, |
| | typename PersistentLocationPolicy, |
| | typename PersistentCheckingPolicy, |
| | typename = std::enable_if_t<std::is_base_of<T, U>::value>> |
| | BasicMember( |
| | const BasicPersistent<U, PersistentWeaknessPolicy, |
| | PersistentLocationPolicy, PersistentCheckingPolicy>& |
| | p) |
| | : BasicMember(p.Get()) {} |
| |
|
| | BasicMember& operator=(const BasicMember& other) { |
| | return operator=(other.Get()); |
| | } |
| | |
| | template <typename U, typename OtherWeaknessTag, typename OtherBarrierPolicy, |
| | typename OtherCheckingPolicy, |
| | typename = std::enable_if_t<std::is_base_of<T, U>::value>> |
| | BasicMember& operator=( |
| | const BasicMember<U, OtherWeaknessTag, OtherBarrierPolicy, |
| | OtherCheckingPolicy>& other) { |
| | return operator=(other.Get()); |
| | } |
| | |
| | template <typename U, typename PersistentWeaknessPolicy, |
| | typename PersistentLocationPolicy, |
| | typename PersistentCheckingPolicy, |
| | typename = std::enable_if_t<std::is_base_of<T, U>::value>> |
| | BasicMember& operator=( |
| | const BasicPersistent<U, PersistentWeaknessPolicy, |
| | PersistentLocationPolicy, PersistentCheckingPolicy>& |
| | other) { |
| | return operator=(other.Get()); |
| | } |
| | BasicMember& operator=(T* other) { |
| | SetRawAtomic(other); |
| | AssigningWriteBarrier(); |
| | this->CheckPointer(Get()); |
| | return *this; |
| | } |
| | BasicMember& operator=(std::nullptr_t) { |
| | Clear(); |
| | return *this; |
| | } |
| | BasicMember& operator=(SentinelPointer s) { |
| | SetRawAtomic(s); |
| | return *this; |
| | } |
| |
|
| | template <typename OtherWeaknessTag, typename OtherBarrierPolicy, |
| | typename OtherCheckingPolicy> |
| | void Swap(BasicMember<T, OtherWeaknessTag, OtherBarrierPolicy, |
| | OtherCheckingPolicy>& other) { |
| | T* tmp = Get(); |
| | *this = other; |
| | other = tmp; |
| | } |
| |
|
| | explicit operator bool() const { return Get(); } |
| | operator T*() const { return Get(); } |
| | T* operator->() const { return Get(); } |
| | T& operator*() const { return *Get(); } |
| |
|
| | T* Get() const { |
| | |
| | return raw_; |
| | } |
| |
|
| | void Clear() { SetRawAtomic(nullptr); } |
| |
|
| | T* Release() { |
| | T* result = Get(); |
| | Clear(); |
| | return result; |
| | } |
| |
|
| | private: |
| | void SetRawAtomic(T* raw) { |
| | reinterpret_cast<std::atomic<T*>*>(&raw_)->store(raw, |
| | std::memory_order_relaxed); |
| | } |
| | T* GetRawAtomic() const { |
| | return reinterpret_cast<const std::atomic<T*>*>(&raw_)->load( |
| | std::memory_order_relaxed); |
| | } |
| |
|
| | void InitializingWriteBarrier() const { |
| | WriteBarrierPolicy::InitializingBarrier( |
| | reinterpret_cast<const void*>(&raw_), static_cast<const void*>(raw_)); |
| | } |
| | void AssigningWriteBarrier() const { |
| | WriteBarrierPolicy::AssigningBarrier(reinterpret_cast<const void*>(&raw_), |
| | static_cast<const void*>(raw_)); |
| | } |
| |
|
| | T* raw_ = nullptr; |
| |
|
| | friend class cppgc::Visitor; |
| | }; |
| |
|
| | template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, |
| | typename CheckingPolicy1, typename T2, typename WeaknessTag2, |
| | typename WriteBarrierPolicy2, typename CheckingPolicy2> |
| | bool operator==( |
| | BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1, |
| | BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2> |
| | member2) { |
| | return member1.Get() == member2.Get(); |
| | } |
| |
|
| | template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1, |
| | typename CheckingPolicy1, typename T2, typename WeaknessTag2, |
| | typename WriteBarrierPolicy2, typename CheckingPolicy2> |
| | bool operator!=( |
| | BasicMember<T1, WeaknessTag1, WriteBarrierPolicy1, CheckingPolicy1> member1, |
| | BasicMember<T2, WeaknessTag2, WriteBarrierPolicy2, CheckingPolicy2> |
| | member2) { |
| | return !(member1 == member2); |
| | } |
| |
|
| | template <typename T, typename WriteBarrierPolicy, typename CheckingPolicy> |
| | struct IsWeak< |
| | internal::BasicMember<T, WeakMemberTag, WriteBarrierPolicy, CheckingPolicy>> |
| | : std::true_type {}; |
| |
|
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | template <typename T> |
| | using Member = internal::BasicMember<T, internal::StrongMemberTag, |
| | internal::DijkstraWriteBarrierPolicy>; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename T> |
| | using WeakMember = internal::BasicMember<T, internal::WeakMemberTag, |
| | internal::DijkstraWriteBarrierPolicy>; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename T> |
| | using UntracedMember = internal::BasicMember<T, internal::UntracedMemberTag, |
| | internal::NoWriteBarrierPolicy>; |
| |
|
| | } |
| |
|
| | #endif |
| |
|