Server IP : 85.214.239.14 / Your IP : 3.147.127.153 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/usr/local/include/node/cppgc/ |
Upload File : |
// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef INCLUDE_CPPGC_PERSISTENT_H_ #define INCLUDE_CPPGC_PERSISTENT_H_ #include <type_traits> #include "cppgc/internal/persistent-node.h" #include "cppgc/internal/pointer-policies.h" #include "cppgc/source-location.h" #include "cppgc/type-traits.h" #include "cppgc/visitor.h" #include "v8config.h" // NOLINT(build/include_directory) namespace cppgc { namespace internal { // The basic class from which all Persistent classes are generated. template <typename T, typename WeaknessPolicy, typename LocationPolicy, typename CheckingPolicy> class BasicPersistent : public LocationPolicy, private WeaknessPolicy, private CheckingPolicy { public: using typename WeaknessPolicy::IsStrongPersistent; using PointeeType = T; // Null-state/sentinel constructors. BasicPersistent( // NOLINT const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc) {} BasicPersistent(std::nullptr_t, // NOLINT const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc) {} BasicPersistent( // NOLINT SentinelPointer s, const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc), raw_(s) {} // Raw value contstructors. BasicPersistent(T* raw, // NOLINT const SourceLocation& loc = SourceLocation::Current()) : LocationPolicy(loc), raw_(raw) { if (!IsValid()) return; node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode( this, &BasicPersistent::Trace); this->CheckPointer(Get()); } BasicPersistent(T& raw, // NOLINT const SourceLocation& loc = SourceLocation::Current()) : BasicPersistent(&raw, loc) {} // Copy ctor. BasicPersistent(const BasicPersistent& other, const SourceLocation& loc = SourceLocation::Current()) : BasicPersistent(other.Get(), loc) {} // Heterogeneous ctor. template <typename U, typename OtherWeaknessPolicy, typename OtherLocationPolicy, typename OtherCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicPersistent( // NOLINT const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy>& other, const SourceLocation& loc = SourceLocation::Current()) : BasicPersistent(other.Get(), loc) {} // Move ctor. The heterogeneous move ctor is not supported since e.g. // persistent can't reuse persistent node from weak persistent. BasicPersistent( BasicPersistent&& other, const SourceLocation& loc = SourceLocation::Current()) noexcept : LocationPolicy(std::move(other)), raw_(std::move(other.raw_)), node_(std::move(other.node_)) { if (!IsValid()) return; node_->UpdateOwner(this); other.raw_ = nullptr; other.node_ = nullptr; this->CheckPointer(Get()); } // Constructor from member. template <typename U, typename MemberBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicPersistent(internal::BasicMember<U, MemberBarrierPolicy, // NOLINT MemberWeaknessTag, MemberCheckingPolicy> member, const SourceLocation& loc = SourceLocation::Current()) : BasicPersistent(member.Get(), loc) {} ~BasicPersistent() { Clear(); } // Copy assignment. BasicPersistent& operator=(const BasicPersistent& other) { return operator=(other.Get()); } template <typename U, typename OtherWeaknessPolicy, typename OtherLocationPolicy, typename OtherCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicPersistent& operator=( const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, OtherCheckingPolicy>& other) { return operator=(other.Get()); } // Move assignment. BasicPersistent& operator=(BasicPersistent&& other) { if (this == &other) return *this; Clear(); LocationPolicy::operator=(std::move(other)); raw_ = std::move(other.raw_); node_ = std::move(other.node_); if (!IsValid()) return *this; node_->UpdateOwner(this); other.raw_ = nullptr; other.node_ = nullptr; this->CheckPointer(Get()); return *this; } // Assignment from member. template <typename U, typename MemberBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename = std::enable_if_t<std::is_base_of<T, U>::value>> BasicPersistent& operator=( internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, MemberCheckingPolicy> member) { return operator=(member.Get()); } BasicPersistent& operator=(T* other) { Assign(other); return *this; } BasicPersistent& operator=(std::nullptr_t) { Clear(); return *this; } BasicPersistent& operator=(SentinelPointer s) { Assign(s); return *this; } 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() { Assign(nullptr); } T* Release() { T* result = Get(); Clear(); return result; } private: static void Trace(Visitor* v, const void* ptr) { const auto* persistent = static_cast<const BasicPersistent*>(ptr); v->TraceRoot(*persistent, persistent->Location()); } bool IsValid() const { // Ideally, handling kSentinelPointer would be done by the embedder. On the // other hand, having Persistent aware of it is beneficial since no node // gets wasted. return raw_ != nullptr && raw_ != kSentinelPointer; } void Assign(T* ptr) { if (IsValid()) { if (ptr && ptr != kSentinelPointer) { // Simply assign the pointer reusing the existing node. raw_ = ptr; this->CheckPointer(ptr); return; } WeaknessPolicy::GetPersistentRegion(raw_).FreeNode(node_); node_ = nullptr; } raw_ = ptr; if (!IsValid()) return; node_ = WeaknessPolicy::GetPersistentRegion(raw_).AllocateNode( this, &BasicPersistent::Trace); this->CheckPointer(Get()); } T* raw_ = nullptr; PersistentNode* node_ = nullptr; }; template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1, typename CheckingPolicy1, typename T2, typename WeaknessPolicy2, typename LocationPolicy2, typename CheckingPolicy2> bool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1, CheckingPolicy1>& p1, const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2, CheckingPolicy2>& p2) { return p1.Get() == p2.Get(); } template <typename T1, typename WeaknessPolicy1, typename LocationPolicy1, typename CheckingPolicy1, typename T2, typename WeaknessPolicy2, typename LocationPolicy2, typename CheckingPolicy2> bool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1, CheckingPolicy1>& p1, const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2, CheckingPolicy2>& p2) { return !(p1 == p2); } template <typename T1, typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy, typename T2, typename MemberWriteBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy> bool operator==(const BasicPersistent<T1, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy>& p, BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, MemberCheckingPolicy> m) { return p.Get() == m.Get(); } template <typename T1, typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy, typename T2, typename MemberWriteBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy> bool operator!=(const BasicPersistent<T1, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy>& p, BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, MemberCheckingPolicy> m) { return !(p == m); } template <typename T1, typename MemberWriteBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename T2, typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy> bool operator==(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, MemberCheckingPolicy> m, const BasicPersistent<T1, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy>& p) { return m.Get() == p.Get(); } template <typename T1, typename MemberWriteBarrierPolicy, typename MemberWeaknessTag, typename MemberCheckingPolicy, typename T2, typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, typename PersistentCheckingPolicy> bool operator!=(BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, MemberCheckingPolicy> m, const BasicPersistent<T1, PersistentWeaknessPolicy, PersistentLocationPolicy, PersistentCheckingPolicy>& p) { return !(m == p); } template <typename T, typename LocationPolicy, typename CheckingPolicy> struct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy, CheckingPolicy>> : std::true_type {}; } // namespace internal /** * Persistent is a way to create a strong pointer from an off-heap object to * another on-heap object. As long as the Persistent handle is alive the GC will * keep the object pointed to alive. The Persistent handle is always a GC root * from the point of view of the GC. Persistent must be constructed and * destructed in the same thread. */ template <typename T> using Persistent = internal::BasicPersistent<T, internal::StrongPersistentPolicy>; /** * WeakPersistent is a way to create a weak pointer from an off-heap object to * an on-heap object. The pointer is automatically cleared when the pointee gets * collected. WeakPersistent must be constructed and destructed in the same * thread. */ template <typename T> using WeakPersistent = internal::BasicPersistent<T, internal::WeakPersistentPolicy>; } // namespace cppgc #endif // INCLUDE_CPPGC_PERSISTENT_H_