11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef INCLUDE_CPPGC_PERSISTENT_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_PERSISTENT_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <type_traits> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "cppgc/internal/persistent-node.h" 111cb0ef41Sopenharmony_ci#include "cppgc/internal/pointer-policies.h" 121cb0ef41Sopenharmony_ci#include "cppgc/sentinel-pointer.h" 131cb0ef41Sopenharmony_ci#include "cppgc/source-location.h" 141cb0ef41Sopenharmony_ci#include "cppgc/type-traits.h" 151cb0ef41Sopenharmony_ci#include "cppgc/visitor.h" 161cb0ef41Sopenharmony_ci#include "v8config.h" // NOLINT(build/include_directory) 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cinamespace cppgc { 191cb0ef41Sopenharmony_cinamespace internal { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci// PersistentBase always refers to the object as const object and defers to 221cb0ef41Sopenharmony_ci// BasicPersistent on casting to the right type as needed. 231cb0ef41Sopenharmony_ciclass PersistentBase { 241cb0ef41Sopenharmony_ci protected: 251cb0ef41Sopenharmony_ci PersistentBase() = default; 261cb0ef41Sopenharmony_ci explicit PersistentBase(const void* raw) : raw_(raw) {} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci const void* GetValue() const { return raw_; } 291cb0ef41Sopenharmony_ci void SetValue(const void* value) { raw_ = value; } 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci PersistentNode* GetNode() const { return node_; } 321cb0ef41Sopenharmony_ci void SetNode(PersistentNode* node) { node_ = node; } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci // Performs a shallow clear which assumes that internal persistent nodes are 351cb0ef41Sopenharmony_ci // destroyed elsewhere. 361cb0ef41Sopenharmony_ci void ClearFromGC() const { 371cb0ef41Sopenharmony_ci raw_ = nullptr; 381cb0ef41Sopenharmony_ci node_ = nullptr; 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci protected: 421cb0ef41Sopenharmony_ci mutable const void* raw_ = nullptr; 431cb0ef41Sopenharmony_ci mutable PersistentNode* node_ = nullptr; 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci friend class PersistentRegionBase; 461cb0ef41Sopenharmony_ci}; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci// The basic class from which all Persistent classes are generated. 491cb0ef41Sopenharmony_citemplate <typename T, typename WeaknessPolicy, typename LocationPolicy, 501cb0ef41Sopenharmony_ci typename CheckingPolicy> 511cb0ef41Sopenharmony_ciclass BasicPersistent final : public PersistentBase, 521cb0ef41Sopenharmony_ci public LocationPolicy, 531cb0ef41Sopenharmony_ci private WeaknessPolicy, 541cb0ef41Sopenharmony_ci private CheckingPolicy { 551cb0ef41Sopenharmony_ci public: 561cb0ef41Sopenharmony_ci using typename WeaknessPolicy::IsStrongPersistent; 571cb0ef41Sopenharmony_ci using PointeeType = T; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // Null-state/sentinel constructors. 601cb0ef41Sopenharmony_ci BasicPersistent( // NOLINT 611cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 621cb0ef41Sopenharmony_ci : LocationPolicy(loc) {} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci BasicPersistent(std::nullptr_t, // NOLINT 651cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 661cb0ef41Sopenharmony_ci : LocationPolicy(loc) {} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci BasicPersistent( // NOLINT 691cb0ef41Sopenharmony_ci SentinelPointer s, const SourceLocation& loc = SourceLocation::Current()) 701cb0ef41Sopenharmony_ci : PersistentBase(s), LocationPolicy(loc) {} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Raw value constructors. 731cb0ef41Sopenharmony_ci BasicPersistent(T* raw, // NOLINT 741cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 751cb0ef41Sopenharmony_ci : PersistentBase(raw), LocationPolicy(loc) { 761cb0ef41Sopenharmony_ci if (!IsValid()) return; 771cb0ef41Sopenharmony_ci SetNode(WeaknessPolicy::GetPersistentRegion(GetValue()) 781cb0ef41Sopenharmony_ci .AllocateNode(this, &TraceAsRoot)); 791cb0ef41Sopenharmony_ci this->CheckPointer(Get()); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci BasicPersistent(T& raw, // NOLINT 831cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 841cb0ef41Sopenharmony_ci : BasicPersistent(&raw, loc) {} 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Copy ctor. 871cb0ef41Sopenharmony_ci BasicPersistent(const BasicPersistent& other, 881cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 891cb0ef41Sopenharmony_ci : BasicPersistent(other.Get(), loc) {} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci // Heterogeneous ctor. 921cb0ef41Sopenharmony_ci template <typename U, typename OtherWeaknessPolicy, 931cb0ef41Sopenharmony_ci typename OtherLocationPolicy, typename OtherCheckingPolicy, 941cb0ef41Sopenharmony_ci typename = std::enable_if_t<std::is_base_of<T, U>::value>> 951cb0ef41Sopenharmony_ci BasicPersistent( 961cb0ef41Sopenharmony_ci const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, 971cb0ef41Sopenharmony_ci OtherCheckingPolicy>& other, 981cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 991cb0ef41Sopenharmony_ci : BasicPersistent(other.Get(), loc) {} 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // Move ctor. The heterogeneous move ctor is not supported since e.g. 1021cb0ef41Sopenharmony_ci // persistent can't reuse persistent node from weak persistent. 1031cb0ef41Sopenharmony_ci BasicPersistent( 1041cb0ef41Sopenharmony_ci BasicPersistent&& other, 1051cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) noexcept 1061cb0ef41Sopenharmony_ci : PersistentBase(std::move(other)), LocationPolicy(std::move(other)) { 1071cb0ef41Sopenharmony_ci if (!IsValid()) return; 1081cb0ef41Sopenharmony_ci GetNode()->UpdateOwner(this); 1091cb0ef41Sopenharmony_ci other.SetValue(nullptr); 1101cb0ef41Sopenharmony_ci other.SetNode(nullptr); 1111cb0ef41Sopenharmony_ci this->CheckPointer(Get()); 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci // Constructor from member. 1151cb0ef41Sopenharmony_ci template <typename U, typename MemberBarrierPolicy, 1161cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 1171cb0ef41Sopenharmony_ci typename MemberStorageType, 1181cb0ef41Sopenharmony_ci typename = std::enable_if_t<std::is_base_of<T, U>::value>> 1191cb0ef41Sopenharmony_ci BasicPersistent(const internal::BasicMember< 1201cb0ef41Sopenharmony_ci U, MemberBarrierPolicy, MemberWeaknessTag, 1211cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& member, 1221cb0ef41Sopenharmony_ci const SourceLocation& loc = SourceLocation::Current()) 1231cb0ef41Sopenharmony_ci : BasicPersistent(member.Get(), loc) {} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci ~BasicPersistent() { Clear(); } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci // Copy assignment. 1281cb0ef41Sopenharmony_ci BasicPersistent& operator=(const BasicPersistent& other) { 1291cb0ef41Sopenharmony_ci return operator=(other.Get()); 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci template <typename U, typename OtherWeaknessPolicy, 1331cb0ef41Sopenharmony_ci typename OtherLocationPolicy, typename OtherCheckingPolicy, 1341cb0ef41Sopenharmony_ci typename = std::enable_if_t<std::is_base_of<T, U>::value>> 1351cb0ef41Sopenharmony_ci BasicPersistent& operator=( 1361cb0ef41Sopenharmony_ci const BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, 1371cb0ef41Sopenharmony_ci OtherCheckingPolicy>& other) { 1381cb0ef41Sopenharmony_ci return operator=(other.Get()); 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci // Move assignment. 1421cb0ef41Sopenharmony_ci BasicPersistent& operator=(BasicPersistent&& other) noexcept { 1431cb0ef41Sopenharmony_ci if (this == &other) return *this; 1441cb0ef41Sopenharmony_ci Clear(); 1451cb0ef41Sopenharmony_ci PersistentBase::operator=(std::move(other)); 1461cb0ef41Sopenharmony_ci LocationPolicy::operator=(std::move(other)); 1471cb0ef41Sopenharmony_ci if (!IsValid()) return *this; 1481cb0ef41Sopenharmony_ci GetNode()->UpdateOwner(this); 1491cb0ef41Sopenharmony_ci other.SetValue(nullptr); 1501cb0ef41Sopenharmony_ci other.SetNode(nullptr); 1511cb0ef41Sopenharmony_ci this->CheckPointer(Get()); 1521cb0ef41Sopenharmony_ci return *this; 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci // Assignment from member. 1561cb0ef41Sopenharmony_ci template <typename U, typename MemberBarrierPolicy, 1571cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 1581cb0ef41Sopenharmony_ci typename MemberStorageType, 1591cb0ef41Sopenharmony_ci typename = std::enable_if_t<std::is_base_of<T, U>::value>> 1601cb0ef41Sopenharmony_ci BasicPersistent& operator=( 1611cb0ef41Sopenharmony_ci const internal::BasicMember<U, MemberBarrierPolicy, MemberWeaknessTag, 1621cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& 1631cb0ef41Sopenharmony_ci member) { 1641cb0ef41Sopenharmony_ci return operator=(member.Get()); 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci BasicPersistent& operator=(T* other) { 1681cb0ef41Sopenharmony_ci Assign(other); 1691cb0ef41Sopenharmony_ci return *this; 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci BasicPersistent& operator=(std::nullptr_t) { 1731cb0ef41Sopenharmony_ci Clear(); 1741cb0ef41Sopenharmony_ci return *this; 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci BasicPersistent& operator=(SentinelPointer s) { 1781cb0ef41Sopenharmony_ci Assign(s); 1791cb0ef41Sopenharmony_ci return *this; 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci explicit operator bool() const { return Get(); } 1831cb0ef41Sopenharmony_ci operator T*() const { return Get(); } 1841cb0ef41Sopenharmony_ci T* operator->() const { return Get(); } 1851cb0ef41Sopenharmony_ci T& operator*() const { return *Get(); } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci // CFI cast exemption to allow passing SentinelPointer through T* and support 1881cb0ef41Sopenharmony_ci // heterogeneous assignments between different Member and Persistent handles 1891cb0ef41Sopenharmony_ci // based on their actual types. 1901cb0ef41Sopenharmony_ci V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const { 1911cb0ef41Sopenharmony_ci // The const_cast below removes the constness from PersistentBase storage. 1921cb0ef41Sopenharmony_ci // The following static_cast re-adds any constness if specified through the 1931cb0ef41Sopenharmony_ci // user-visible template parameter T. 1941cb0ef41Sopenharmony_ci return static_cast<T*>(const_cast<void*>(GetValue())); 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci void Clear() { 1981cb0ef41Sopenharmony_ci // Simplified version of `Assign()` to allow calling without a complete type 1991cb0ef41Sopenharmony_ci // `T`. 2001cb0ef41Sopenharmony_ci if (IsValid()) { 2011cb0ef41Sopenharmony_ci WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 2021cb0ef41Sopenharmony_ci SetNode(nullptr); 2031cb0ef41Sopenharmony_ci } 2041cb0ef41Sopenharmony_ci SetValue(nullptr); 2051cb0ef41Sopenharmony_ci } 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci T* Release() { 2081cb0ef41Sopenharmony_ci T* result = Get(); 2091cb0ef41Sopenharmony_ci Clear(); 2101cb0ef41Sopenharmony_ci return result; 2111cb0ef41Sopenharmony_ci } 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci template <typename U, typename OtherWeaknessPolicy = WeaknessPolicy, 2141cb0ef41Sopenharmony_ci typename OtherLocationPolicy = LocationPolicy, 2151cb0ef41Sopenharmony_ci typename OtherCheckingPolicy = CheckingPolicy> 2161cb0ef41Sopenharmony_ci BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, 2171cb0ef41Sopenharmony_ci OtherCheckingPolicy> 2181cb0ef41Sopenharmony_ci To() const { 2191cb0ef41Sopenharmony_ci return BasicPersistent<U, OtherWeaknessPolicy, OtherLocationPolicy, 2201cb0ef41Sopenharmony_ci OtherCheckingPolicy>(static_cast<U*>(Get())); 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci private: 2241cb0ef41Sopenharmony_ci static void TraceAsRoot(RootVisitor& root_visitor, const void* ptr) { 2251cb0ef41Sopenharmony_ci root_visitor.Trace(*static_cast<const BasicPersistent*>(ptr)); 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci bool IsValid() const { 2291cb0ef41Sopenharmony_ci // Ideally, handling kSentinelPointer would be done by the embedder. On the 2301cb0ef41Sopenharmony_ci // other hand, having Persistent aware of it is beneficial since no node 2311cb0ef41Sopenharmony_ci // gets wasted. 2321cb0ef41Sopenharmony_ci return GetValue() != nullptr && GetValue() != kSentinelPointer; 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci void Assign(T* ptr) { 2361cb0ef41Sopenharmony_ci if (IsValid()) { 2371cb0ef41Sopenharmony_ci if (ptr && ptr != kSentinelPointer) { 2381cb0ef41Sopenharmony_ci // Simply assign the pointer reusing the existing node. 2391cb0ef41Sopenharmony_ci SetValue(ptr); 2401cb0ef41Sopenharmony_ci this->CheckPointer(ptr); 2411cb0ef41Sopenharmony_ci return; 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 2441cb0ef41Sopenharmony_ci SetNode(nullptr); 2451cb0ef41Sopenharmony_ci } 2461cb0ef41Sopenharmony_ci SetValue(ptr); 2471cb0ef41Sopenharmony_ci if (!IsValid()) return; 2481cb0ef41Sopenharmony_ci SetNode(WeaknessPolicy::GetPersistentRegion(GetValue()) 2491cb0ef41Sopenharmony_ci .AllocateNode(this, &TraceAsRoot)); 2501cb0ef41Sopenharmony_ci this->CheckPointer(Get()); 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci void ClearFromGC() const { 2541cb0ef41Sopenharmony_ci if (IsValid()) { 2551cb0ef41Sopenharmony_ci WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 2561cb0ef41Sopenharmony_ci PersistentBase::ClearFromGC(); 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci } 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci // Set Get() for details. 2611cb0ef41Sopenharmony_ci V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") 2621cb0ef41Sopenharmony_ci T* GetFromGC() const { 2631cb0ef41Sopenharmony_ci return static_cast<T*>(const_cast<void*>(GetValue())); 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci friend class internal::RootVisitor; 2671cb0ef41Sopenharmony_ci}; 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_citemplate <typename T1, typename WeaknessPolicy1, typename LocationPolicy1, 2701cb0ef41Sopenharmony_ci typename CheckingPolicy1, typename T2, typename WeaknessPolicy2, 2711cb0ef41Sopenharmony_ci typename LocationPolicy2, typename CheckingPolicy2> 2721cb0ef41Sopenharmony_cibool operator==(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1, 2731cb0ef41Sopenharmony_ci CheckingPolicy1>& p1, 2741cb0ef41Sopenharmony_ci const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2, 2751cb0ef41Sopenharmony_ci CheckingPolicy2>& p2) { 2761cb0ef41Sopenharmony_ci return p1.Get() == p2.Get(); 2771cb0ef41Sopenharmony_ci} 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_citemplate <typename T1, typename WeaknessPolicy1, typename LocationPolicy1, 2801cb0ef41Sopenharmony_ci typename CheckingPolicy1, typename T2, typename WeaknessPolicy2, 2811cb0ef41Sopenharmony_ci typename LocationPolicy2, typename CheckingPolicy2> 2821cb0ef41Sopenharmony_cibool operator!=(const BasicPersistent<T1, WeaknessPolicy1, LocationPolicy1, 2831cb0ef41Sopenharmony_ci CheckingPolicy1>& p1, 2841cb0ef41Sopenharmony_ci const BasicPersistent<T2, WeaknessPolicy2, LocationPolicy2, 2851cb0ef41Sopenharmony_ci CheckingPolicy2>& p2) { 2861cb0ef41Sopenharmony_ci return !(p1 == p2); 2871cb0ef41Sopenharmony_ci} 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_citemplate <typename T1, typename PersistentWeaknessPolicy, 2901cb0ef41Sopenharmony_ci typename PersistentLocationPolicy, typename PersistentCheckingPolicy, 2911cb0ef41Sopenharmony_ci typename T2, typename MemberWriteBarrierPolicy, 2921cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 2931cb0ef41Sopenharmony_ci typename MemberStorageType> 2941cb0ef41Sopenharmony_cibool operator==( 2951cb0ef41Sopenharmony_ci const BasicPersistent<T1, PersistentWeaknessPolicy, 2961cb0ef41Sopenharmony_ci PersistentLocationPolicy, PersistentCheckingPolicy>& 2971cb0ef41Sopenharmony_ci p, 2981cb0ef41Sopenharmony_ci const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, 2991cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& m) { 3001cb0ef41Sopenharmony_ci return p.Get() == m.Get(); 3011cb0ef41Sopenharmony_ci} 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_citemplate <typename T1, typename PersistentWeaknessPolicy, 3041cb0ef41Sopenharmony_ci typename PersistentLocationPolicy, typename PersistentCheckingPolicy, 3051cb0ef41Sopenharmony_ci typename T2, typename MemberWriteBarrierPolicy, 3061cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 3071cb0ef41Sopenharmony_ci typename MemberStorageType> 3081cb0ef41Sopenharmony_cibool operator!=( 3091cb0ef41Sopenharmony_ci const BasicPersistent<T1, PersistentWeaknessPolicy, 3101cb0ef41Sopenharmony_ci PersistentLocationPolicy, PersistentCheckingPolicy>& 3111cb0ef41Sopenharmony_ci p, 3121cb0ef41Sopenharmony_ci const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, 3131cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& m) { 3141cb0ef41Sopenharmony_ci return !(p == m); 3151cb0ef41Sopenharmony_ci} 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_citemplate <typename T1, typename MemberWriteBarrierPolicy, 3181cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 3191cb0ef41Sopenharmony_ci typename MemberStorageType, typename T2, 3201cb0ef41Sopenharmony_ci typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, 3211cb0ef41Sopenharmony_ci typename PersistentCheckingPolicy> 3221cb0ef41Sopenharmony_cibool operator==( 3231cb0ef41Sopenharmony_ci const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, 3241cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& m, 3251cb0ef41Sopenharmony_ci const BasicPersistent<T1, PersistentWeaknessPolicy, 3261cb0ef41Sopenharmony_ci PersistentLocationPolicy, PersistentCheckingPolicy>& 3271cb0ef41Sopenharmony_ci p) { 3281cb0ef41Sopenharmony_ci return m.Get() == p.Get(); 3291cb0ef41Sopenharmony_ci} 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_citemplate <typename T1, typename MemberWriteBarrierPolicy, 3321cb0ef41Sopenharmony_ci typename MemberWeaknessTag, typename MemberCheckingPolicy, 3331cb0ef41Sopenharmony_ci typename MemberStorageType, typename T2, 3341cb0ef41Sopenharmony_ci typename PersistentWeaknessPolicy, typename PersistentLocationPolicy, 3351cb0ef41Sopenharmony_ci typename PersistentCheckingPolicy> 3361cb0ef41Sopenharmony_cibool operator!=( 3371cb0ef41Sopenharmony_ci const BasicMember<T2, MemberWeaknessTag, MemberWriteBarrierPolicy, 3381cb0ef41Sopenharmony_ci MemberCheckingPolicy, MemberStorageType>& m, 3391cb0ef41Sopenharmony_ci const BasicPersistent<T1, PersistentWeaknessPolicy, 3401cb0ef41Sopenharmony_ci PersistentLocationPolicy, PersistentCheckingPolicy>& 3411cb0ef41Sopenharmony_ci p) { 3421cb0ef41Sopenharmony_ci return !(m == p); 3431cb0ef41Sopenharmony_ci} 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_citemplate <typename T, typename LocationPolicy, typename CheckingPolicy> 3461cb0ef41Sopenharmony_cistruct IsWeak<BasicPersistent<T, internal::WeakPersistentPolicy, LocationPolicy, 3471cb0ef41Sopenharmony_ci CheckingPolicy>> : std::true_type {}; 3481cb0ef41Sopenharmony_ci} // namespace internal 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci/** 3511cb0ef41Sopenharmony_ci * Persistent is a way to create a strong pointer from an off-heap object to 3521cb0ef41Sopenharmony_ci * another on-heap object. As long as the Persistent handle is alive the GC will 3531cb0ef41Sopenharmony_ci * keep the object pointed to alive. The Persistent handle is always a GC root 3541cb0ef41Sopenharmony_ci * from the point of view of the GC. Persistent must be constructed and 3551cb0ef41Sopenharmony_ci * destructed in the same thread. 3561cb0ef41Sopenharmony_ci */ 3571cb0ef41Sopenharmony_citemplate <typename T> 3581cb0ef41Sopenharmony_ciusing Persistent = 3591cb0ef41Sopenharmony_ci internal::BasicPersistent<T, internal::StrongPersistentPolicy>; 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ci/** 3621cb0ef41Sopenharmony_ci * WeakPersistent is a way to create a weak pointer from an off-heap object to 3631cb0ef41Sopenharmony_ci * an on-heap object. The pointer is automatically cleared when the pointee gets 3641cb0ef41Sopenharmony_ci * collected. WeakPersistent must be constructed and destructed in the same 3651cb0ef41Sopenharmony_ci * thread. 3661cb0ef41Sopenharmony_ci */ 3671cb0ef41Sopenharmony_citemplate <typename T> 3681cb0ef41Sopenharmony_ciusing WeakPersistent = 3691cb0ef41Sopenharmony_ci internal::BasicPersistent<T, internal::WeakPersistentPolicy>; 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci} // namespace cppgc 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci#endif // INCLUDE_CPPGC_PERSISTENT_H_ 374