Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/node/cppgc/persistent.h
$ cat -n /usr/include/node/cppgc/persistent.h 1 // Copyright 2020 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef INCLUDE_CPPGC_PERSISTENT_H_ 6 #define INCLUDE_CPPGC_PERSISTENT_H_ 7 8 #include
9 10 #include "cppgc/internal/persistent-node.h" 11 #include "cppgc/internal/pointer-policies.h" 12 #include "cppgc/sentinel-pointer.h" 13 #include "cppgc/source-location.h" 14 #include "cppgc/type-traits.h" 15 #include "cppgc/visitor.h" 16 #include "v8config.h" // NOLINT(build/include_directory) 17 18 namespace cppgc { 19 namespace internal { 20 21 // PersistentBase always refers to the object as const object and defers to 22 // BasicPersistent on casting to the right type as needed. 23 class PersistentBase { 24 protected: 25 PersistentBase() = default; 26 explicit PersistentBase(const void* raw) : raw_(raw) {} 27 28 const void* GetValue() const { return raw_; } 29 void SetValue(const void* value) { raw_ = value; } 30 31 PersistentNode* GetNode() const { return node_; } 32 void SetNode(PersistentNode* node) { node_ = node; } 33 34 // Performs a shallow clear which assumes that internal persistent nodes are 35 // destroyed elsewhere. 36 void ClearFromGC() const { 37 raw_ = nullptr; 38 node_ = nullptr; 39 } 40 41 protected: 42 mutable const void* raw_ = nullptr; 43 mutable PersistentNode* node_ = nullptr; 44 45 friend class PersistentRegionBase; 46 }; 47 48 // The basic class from which all Persistent classes are generated. 49 template
51 class BasicPersistent final : public PersistentBase, 52 public LocationPolicy, 53 private WeaknessPolicy, 54 private CheckingPolicy { 55 public: 56 using typename WeaknessPolicy::IsStrongPersistent; 57 using PointeeType = T; 58 59 // Null-state/sentinel constructors. 60 BasicPersistent( // NOLINT 61 const SourceLocation& loc = SourceLocation::Current()) 62 : LocationPolicy(loc) {} 63 64 BasicPersistent(std::nullptr_t, // NOLINT 65 const SourceLocation& loc = SourceLocation::Current()) 66 : LocationPolicy(loc) {} 67 68 BasicPersistent( // NOLINT 69 SentinelPointer s, const SourceLocation& loc = SourceLocation::Current()) 70 : PersistentBase(s), LocationPolicy(loc) {} 71 72 // Raw value constructors. 73 BasicPersistent(T* raw, // NOLINT 74 const SourceLocation& loc = SourceLocation::Current()) 75 : PersistentBase(raw), LocationPolicy(loc) { 76 if (!IsValid()) return; 77 SetNode(WeaknessPolicy::GetPersistentRegion(GetValue()) 78 .AllocateNode(this, &TraceAsRoot)); 79 this->CheckPointer(Get()); 80 } 81 82 BasicPersistent(T& raw, // NOLINT 83 const SourceLocation& loc = SourceLocation::Current()) 84 : BasicPersistent(&raw, loc) {} 85 86 // Copy ctor. 87 BasicPersistent(const BasicPersistent& other, 88 const SourceLocation& loc = SourceLocation::Current()) 89 : BasicPersistent(other.Get(), loc) {} 90 91 // Heterogeneous ctor. 92 template
::value>> 95 // NOLINTNEXTLINE 96 BasicPersistent( 97 const BasicPersistent
& other, 99 const SourceLocation& loc = SourceLocation::Current()) 100 : BasicPersistent(other.Get(), loc) {} 101 102 // Move ctor. The heterogeneous move ctor is not supported since e.g. 103 // persistent can't reuse persistent node from weak persistent. 104 BasicPersistent( 105 BasicPersistent&& other, 106 const SourceLocation& loc = SourceLocation::Current()) noexcept 107 : PersistentBase(std::move(other)), LocationPolicy(std::move(other)) { 108 if (!IsValid()) return; 109 GetNode()->UpdateOwner(this); 110 other.SetValue(nullptr); 111 other.SetNode(nullptr); 112 this->CheckPointer(Get()); 113 } 114 115 // Constructor from member. 116 template
::value>> 120 // NOLINTNEXTLINE 121 BasicPersistent(const internal::BasicMember< 122 U, MemberBarrierPolicy, MemberWeaknessTag, 123 MemberCheckingPolicy, MemberStorageType>& member, 124 const SourceLocation& loc = SourceLocation::Current()) 125 : BasicPersistent(member.Get(), loc) {} 126 127 ~BasicPersistent() { Clear(); } 128 129 // Copy assignment. 130 BasicPersistent& operator=(const BasicPersistent& other) { 131 return operator=(other.Get()); 132 } 133 134 template
::value>> 137 BasicPersistent& operator=( 138 const BasicPersistent
& other) { 140 return operator=(other.Get()); 141 } 142 143 // Move assignment. 144 BasicPersistent& operator=(BasicPersistent&& other) noexcept { 145 if (this == &other) return *this; 146 Clear(); 147 PersistentBase::operator=(std::move(other)); 148 LocationPolicy::operator=(std::move(other)); 149 if (!IsValid()) return *this; 150 GetNode()->UpdateOwner(this); 151 other.SetValue(nullptr); 152 other.SetNode(nullptr); 153 this->CheckPointer(Get()); 154 return *this; 155 } 156 157 // Assignment from member. 158 template
::value>> 162 BasicPersistent& operator=( 163 const internal::BasicMember
& 165 member) { 166 return operator=(member.Get()); 167 } 168 169 BasicPersistent& operator=(T* other) { 170 Assign(other); 171 return *this; 172 } 173 174 BasicPersistent& operator=(std::nullptr_t) { 175 Clear(); 176 return *this; 177 } 178 179 BasicPersistent& operator=(SentinelPointer s) { 180 Assign(s); 181 return *this; 182 } 183 184 explicit operator bool() const { return Get(); } 185 // Historically we allow implicit conversions to T*. 186 // NOLINTNEXTLINE 187 operator T*() const { return Get(); } 188 T* operator->() const { return Get(); } 189 T& operator*() const { return *Get(); } 190 191 // CFI cast exemption to allow passing SentinelPointer through T* and support 192 // heterogeneous assignments between different Member and Persistent handles 193 // based on their actual types. 194 V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const { 195 // The const_cast below removes the constness from PersistentBase storage. 196 // The following static_cast re-adds any constness if specified through the 197 // user-visible template parameter T. 198 return static_cast
(const_cast
(GetValue())); 199 } 200 201 void Clear() { 202 // Simplified version of `Assign()` to allow calling without a complete type 203 // `T`. 204 if (IsValid()) { 205 WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 206 SetNode(nullptr); 207 } 208 SetValue(nullptr); 209 } 210 211 T* Release() { 212 T* result = Get(); 213 Clear(); 214 return result; 215 } 216 217 template
220 BasicPersistent
222 To() const { 223 return BasicPersistent
(static_cast
(Get())); 225 } 226 227 private: 228 static void TraceAsRoot(RootVisitor& root_visitor, const void* ptr) { 229 root_visitor.Trace(*static_cast
(ptr)); 230 } 231 232 bool IsValid() const { 233 // Ideally, handling kSentinelPointer would be done by the embedder. On the 234 // other hand, having Persistent aware of it is beneficial since no node 235 // gets wasted. 236 return GetValue() != nullptr && GetValue() != kSentinelPointer; 237 } 238 239 void Assign(T* ptr) { 240 if (IsValid()) { 241 if (ptr && ptr != kSentinelPointer) { 242 // Simply assign the pointer reusing the existing node. 243 SetValue(ptr); 244 this->CheckPointer(ptr); 245 return; 246 } 247 WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 248 SetNode(nullptr); 249 } 250 SetValue(ptr); 251 if (!IsValid()) return; 252 SetNode(WeaknessPolicy::GetPersistentRegion(GetValue()) 253 .AllocateNode(this, &TraceAsRoot)); 254 this->CheckPointer(Get()); 255 } 256 257 void ClearFromGC() const { 258 if (IsValid()) { 259 WeaknessPolicy::GetPersistentRegion(GetValue()).FreeNode(GetNode()); 260 PersistentBase::ClearFromGC(); 261 } 262 } 263 264 // Set Get() for details. 265 V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") 266 T* GetFromGC() const { 267 return static_cast
(const_cast
(GetValue())); 268 } 269 270 friend class internal::RootVisitor; 271 }; 272 273 template
276 bool operator==(const BasicPersistent
& p1, 278 const BasicPersistent
& p2) { 280 return p1.Get() == p2.Get(); 281 } 282 283 template
286 bool operator!=(const BasicPersistent
& p1, 288 const BasicPersistent
& p2) { 290 return !(p1 == p2); 291 } 292 293 template
298 bool operator==( 299 const BasicPersistent
& 301 p, 302 const BasicMember
& m) { 304 return p.Get() == m.Get(); 305 } 306 307 template
312 bool operator!=( 313 const BasicPersistent
& 315 p, 316 const BasicMember
& m) { 318 return !(p == m); 319 } 320 321 template
326 bool operator==( 327 const BasicMember
& m, 329 const BasicPersistent
& 331 p) { 332 return m.Get() == p.Get(); 333 } 334 335 template
340 bool operator!=( 341 const BasicMember
& m, 343 const BasicPersistent
& 345 p) { 346 return !(m == p); 347 } 348 349 template
350 struct IsWeak
> : std::true_type {}; 352 } // namespace internal 353 354 /** 355 * Persistent is a way to create a strong pointer from an off-heap object to 356 * another on-heap object. As long as the Persistent handle is alive the GC will 357 * keep the object pointed to alive. The Persistent handle is always a GC root 358 * from the point of view of the GC. Persistent must be constructed and 359 * destructed in the same thread. 360 */ 361 template
362 using Persistent = 363 internal::BasicPersistent
; 364 365 /** 366 * WeakPersistent is a way to create a weak pointer from an off-heap object to 367 * an on-heap object. The pointer is automatically cleared when the pointee gets 368 * collected. WeakPersistent must be constructed and destructed in the same 369 * thread. 370 */ 371 template
372 using WeakPersistent = 373 internal::BasicPersistent
; 374 375 } // namespace cppgc 376 377 #endif // INCLUDE_CPPGC_PERSISTENT_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2026 MyWebUniversity.com ™