Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/node/cppgc/visitor.h
$ cat -n /usr/include/node/cppgc/visitor.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_VISITOR_H_ 6 #define INCLUDE_CPPGC_VISITOR_H_ 7 8 #include
9 10 #include "cppgc/custom-space.h" 11 #include "cppgc/ephemeron-pair.h" 12 #include "cppgc/garbage-collected.h" 13 #include "cppgc/internal/logging.h" 14 #include "cppgc/internal/member-storage.h" 15 #include "cppgc/internal/pointer-policies.h" 16 #include "cppgc/liveness-broker.h" 17 #include "cppgc/member.h" 18 #include "cppgc/sentinel-pointer.h" 19 #include "cppgc/source-location.h" 20 #include "cppgc/trace-trait.h" 21 #include "cppgc/type-traits.h" 22 23 namespace cppgc { 24 25 namespace internal { 26 template
28 class BasicCrossThreadPersistent; 29 template
31 class BasicPersistent; 32 class ConservativeTracingVisitor; 33 class VisitorBase; 34 class VisitorFactory; 35 } // namespace internal 36 37 using WeakCallback = void (*)(const LivenessBroker&, const void*); 38 39 /** 40 * Visitor passed to trace methods. All managed pointers must have called the 41 * Visitor's trace method on them. 42 * 43 * \code 44 * class Foo final : public GarbageCollected
{ 45 * public: 46 * void Trace(Visitor* visitor) const { 47 * visitor->Trace(foo_); 48 * visitor->Trace(weak_foo_); 49 * } 50 * private: 51 * Member
foo_; 52 * WeakMember
weak_foo_; 53 * }; 54 * \endcode 55 */ 56 class V8_EXPORT Visitor { 57 public: 58 class Key { 59 private: 60 Key() = default; 61 friend class internal::VisitorFactory; 62 }; 63 64 explicit Visitor(Key) {} 65 66 virtual ~Visitor() = default; 67 68 /** 69 * Trace method for Member. 70 * 71 * \param member Member reference retaining an object. 72 */ 73 template
74 void Trace(const Member
& member) { 75 const T* value = member.GetRawAtomic(); 76 CPPGC_DCHECK(value != kSentinelPointer); 77 TraceImpl(value); 78 } 79 80 /** 81 * Trace method for WeakMember. 82 * 83 * \param weak_member WeakMember reference weakly retaining an object. 84 */ 85 template
86 void Trace(const WeakMember
& weak_member) { 87 static_assert(sizeof(T), "Pointee type must be fully defined."); 88 static_assert(internal::IsGarbageCollectedOrMixinType
::value, 89 "T must be GarbageCollected or GarbageCollectedMixin type"); 90 static_assert(!internal::IsAllocatedOnCompactableSpace
::value, 91 "Weak references to compactable objects are not allowed"); 92 93 const T* value = weak_member.GetRawAtomic(); 94 95 // Bailout assumes that WeakMember emits write barrier. 96 if (!value) { 97 return; 98 } 99 100 CPPGC_DCHECK(value != kSentinelPointer); 101 VisitWeak(value, TraceTrait
::GetTraceDescriptor(value), 102 &HandleWeak
>, &weak_member); 103 } 104 105 #if defined(CPPGC_POINTER_COMPRESSION) 106 /** 107 * Trace method for UncompressedMember. 108 * 109 * \param member UncompressedMember reference retaining an object. 110 */ 111 template
112 void Trace(const subtle::UncompressedMember
& member) { 113 const T* value = member.GetRawAtomic(); 114 CPPGC_DCHECK(value != kSentinelPointer); 115 TraceImpl(value); 116 } 117 #endif // defined(CPPGC_POINTER_COMPRESSION) 118 119 template
120 void TraceMultiple(const subtle::UncompressedMember
* start, size_t len) { 121 static_assert(sizeof(T), "Pointee type must be fully defined."); 122 static_assert(internal::IsGarbageCollectedOrMixinType
::value, 123 "T must be GarbageCollected or GarbageCollectedMixin type"); 124 VisitMultipleUncompressedMember(start, len, 125 &TraceTrait
::GetTraceDescriptor); 126 } 127 128 template
, subtle::UncompressedMember
>>* = nullptr> 131 void TraceMultiple(const Member
* start, size_t len) { 132 static_assert(sizeof(T), "Pointee type must be fully defined."); 133 static_assert(internal::IsGarbageCollectedOrMixinType
::value, 134 "T must be GarbageCollected or GarbageCollectedMixin type"); 135 #if defined(CPPGC_POINTER_COMPRESSION) 136 static_assert(std::is_same_v
, subtle::CompressedMember
>, 137 "Member and CompressedMember must be the same."); 138 VisitMultipleCompressedMember(start, len, 139 &TraceTrait
::GetTraceDescriptor); 140 #endif // defined(CPPGC_POINTER_COMPRESSION) 141 } 142 143 /** 144 * Trace method for inlined objects that are not allocated themselves but 145 * otherwise follow managed heap layout and have a Trace() method. 146 * 147 * \param object reference of the inlined object. 148 */ 149 template
150 void Trace(const T& object) { 151 #if V8_ENABLE_CHECKS 152 // This object is embedded in potentially multiple nested objects. The 153 // outermost object must not be in construction as such objects are (a) not 154 // processed immediately, and (b) only processed conservatively if not 155 // otherwise possible. 156 CheckObjectNotInConstruction(&object); 157 #endif // V8_ENABLE_CHECKS 158 TraceTrait
::Trace(this, &object); 159 } 160 161 template
162 void TraceMultiple(const T* start, size_t len) { 163 #if V8_ENABLE_CHECKS 164 // This object is embedded in potentially multiple nested objects. The 165 // outermost object must not be in construction as such objects are (a) not 166 // processed immediately, and (b) only processed conservatively if not 167 // otherwise possible. 168 CheckObjectNotInConstruction(start); 169 #endif // V8_ENABLE_CHECKS 170 for (size_t i = 0; i < len; ++i) { 171 const T* object = &start[i]; 172 if constexpr (std::is_polymorphic_v
) { 173 // The object's vtable may be uninitialized in which case the object is 174 // not traced. 175 if (*reinterpret_cast
(object) == 0) continue; 176 } 177 TraceTrait
::Trace(this, object); 178 } 179 } 180 181 /** 182 * Registers a weak callback method on the object of type T. See 183 * LivenessBroker for an usage example. 184 * 185 * \param object of type T specifying a weak callback method. 186 */ 187 template
188 void RegisterWeakCallbackMethod(const T* object) { 189 RegisterWeakCallback(&WeakCallbackMethodDelegate
, object); 190 } 191 192 /** 193 * Trace method for EphemeronPair. 194 * 195 * \param ephemeron_pair EphemeronPair reference weakly retaining a key object 196 * and strongly retaining a value object in case the key object is alive. 197 */ 198 template
199 void Trace(const EphemeronPair
& ephemeron_pair) { 200 TraceEphemeron(ephemeron_pair.key, &ephemeron_pair.value); 201 RegisterWeakCallbackMethod
, 202 &EphemeronPair
::ClearValueIfKeyIsDead>( 203 &ephemeron_pair); 204 } 205 206 /** 207 * Trace method for a single ephemeron. Used for tracing a raw ephemeron in 208 * which the `key` and `value` are kept separately. 209 * 210 * \param weak_member_key WeakMember reference weakly retaining a key object. 211 * \param member_value Member reference with ephemeron semantics. 212 */ 213 template
214 void TraceEphemeron(const WeakMember
& weak_member_key, 215 const Member
* member_value) { 216 const KeyType* key = weak_member_key.GetRawAtomic(); 217 if (!key) return; 218 219 // `value` must always be non-null. 220 CPPGC_DCHECK(member_value); 221 const ValueType* value = member_value->GetRawAtomic(); 222 if (!value) return; 223 224 // KeyType and ValueType may refer to GarbageCollectedMixin. 225 TraceDescriptor value_desc = 226 TraceTrait
::GetTraceDescriptor(value); 227 CPPGC_DCHECK(value_desc.base_object_payload); 228 const void* key_base_object_payload = 229 TraceTrait
::GetTraceDescriptor(key).base_object_payload; 230 CPPGC_DCHECK(key_base_object_payload); 231 232 VisitEphemeron(key_base_object_payload, value, value_desc); 233 } 234 235 /** 236 * Trace method for a single ephemeron. Used for tracing a raw ephemeron in 237 * which the `key` and `value` are kept separately. Note that this overload 238 * is for non-GarbageCollected `value`s that can be traced though. 239 * 240 * \param key `WeakMember` reference weakly retaining a key object. 241 * \param value Reference weakly retaining a value object. Note that 242 * `ValueType` here should not be `Member`. It is expected that 243 * `TraceTrait
::GetTraceDescriptor(value)` returns a 244 * `TraceDescriptor` with a null base pointer but a valid trace method. 245 */ 246 template
247 void TraceEphemeron(const WeakMember
& weak_member_key, 248 const ValueType* value) { 249 static_assert(!IsGarbageCollectedOrMixinTypeV
, 250 "garbage-collected types must use WeakMember and Member"); 251 const KeyType* key = weak_member_key.GetRawAtomic(); 252 if (!key) return; 253 254 // `value` must always be non-null. 255 CPPGC_DCHECK(value); 256 TraceDescriptor value_desc = 257 TraceTrait
::GetTraceDescriptor(value); 258 // `value_desc.base_object_payload` must be null as this override is only 259 // taken for non-garbage-collected values. 260 CPPGC_DCHECK(!value_desc.base_object_payload); 261 262 // KeyType might be a GarbageCollectedMixin. 263 const void* key_base_object_payload = 264 TraceTrait
::GetTraceDescriptor(key).base_object_payload; 265 CPPGC_DCHECK(key_base_object_payload); 266 267 VisitEphemeron(key_base_object_payload, value, value_desc); 268 } 269 270 /** 271 * Trace method that strongifies a WeakMember. 272 * 273 * \param weak_member WeakMember reference retaining an object. 274 */ 275 template
276 void TraceStrongly(const WeakMember
& weak_member) { 277 const T* value = weak_member.GetRawAtomic(); 278 CPPGC_DCHECK(value != kSentinelPointer); 279 TraceImpl(value); 280 } 281 282 /** 283 * Trace method for retaining containers strongly. 284 * 285 * \param object reference to the container. 286 */ 287 template
288 void TraceStrongContainer(const T* object) { 289 TraceImpl(object); 290 } 291 292 /** 293 * Trace method for retaining containers weakly. Note that weak containers 294 * should emit write barriers. 295 * 296 * \param object reference to the container. 297 * \param callback to be invoked. 298 * \param callback_data custom data that is passed to the callback. 299 */ 300 template
301 void TraceWeakContainer(const T* object, WeakCallback callback, 302 const void* callback_data) { 303 if (!object) return; 304 VisitWeakContainer(object, TraceTrait
::GetTraceDescriptor(object), 305 TraceTrait
::GetWeakTraceDescriptor(object), callback, 306 callback_data); 307 } 308 309 /** 310 * Registers a slot containing a reference to an object allocated on a 311 * compactable space. Such references maybe be arbitrarily moved by the GC. 312 * 313 * \param slot location of reference to object that might be moved by the GC. 314 * The slot must contain an uncompressed pointer. 315 */ 316 template
317 void RegisterMovableReference(const T** slot) { 318 static_assert(internal::IsAllocatedOnCompactableSpace
::value, 319 "Only references to objects allocated on compactable spaces " 320 "should be registered as movable slots."); 321 static_assert(!IsGarbageCollectedMixinTypeV
, 322 "Mixin types do not support compaction."); 323 HandleMovableReference(reinterpret_cast
(slot)); 324 } 325 326 /** 327 * Registers a weak callback that is invoked during garbage collection. 328 * 329 * \param callback to be invoked. 330 * \param data custom data that is passed to the callback. 331 */ 332 virtual void RegisterWeakCallback(WeakCallback callback, const void* data) {} 333 334 /** 335 * Defers tracing an object from a concurrent thread to the mutator thread. 336 * Should be called by Trace methods of types that are not safe to trace 337 * concurrently. 338 * 339 * \param parameter tells the trace callback which object was deferred. 340 * \param callback to be invoked for tracing on the mutator thread. 341 * \param deferred_size size of deferred object. 342 * 343 * \returns false if the object does not need to be deferred (i.e. currently 344 * traced on the mutator thread) and true otherwise (i.e. currently traced on 345 * a concurrent thread). 346 */ 347 virtual V8_WARN_UNUSED_RESULT bool DeferTraceToMutatorThreadIfConcurrent( 348 const void* parameter, TraceCallback callback, size_t deferred_size) { 349 // By default tracing is not deferred. 350 return false; 351 } 352 353 protected: 354 virtual void Visit(const void* self, TraceDescriptor) {} 355 virtual void VisitWeak(const void* self, TraceDescriptor, WeakCallback, 356 const void* weak_member) {} 357 virtual void VisitEphemeron(const void* key, const void* value, 358 TraceDescriptor value_desc) {} 359 virtual void VisitWeakContainer(const void* self, TraceDescriptor strong_desc, 360 TraceDescriptor weak_desc, 361 WeakCallback callback, const void* data) {} 362 virtual void HandleMovableReference(const void**) {} 363 364 virtual void VisitMultipleUncompressedMember( 365 const void* start, size_t len, 366 TraceDescriptorCallback get_trace_descriptor) { 367 // Default implementation merely delegates to Visit(). 368 const char* it = static_cast
(start); 369 const char* end = it + len * internal::kSizeOfUncompressedMember; 370 for (; it < end; it += internal::kSizeOfUncompressedMember) { 371 const auto* current = reinterpret_cast
(it); 372 const void* object = current->LoadAtomic(); 373 if (!object) continue; 374 375 Visit(object, get_trace_descriptor(object)); 376 } 377 } 378 379 #if defined(CPPGC_POINTER_COMPRESSION) 380 virtual void VisitMultipleCompressedMember( 381 const void* start, size_t len, 382 TraceDescriptorCallback get_trace_descriptor) { 383 // Default implementation merely delegates to Visit(). 384 const char* it = static_cast
(start); 385 const char* end = it + len * internal::kSizeofCompressedMember; 386 for (; it < end; it += internal::kSizeofCompressedMember) { 387 const auto* current = 388 reinterpret_cast
(it); 389 const void* object = current->LoadAtomic(); 390 if (!object) continue; 391 392 Visit(object, get_trace_descriptor(object)); 393 } 394 } 395 #endif // defined(CPPGC_POINTER_COMPRESSION) 396 397 private: 398 template
399 static void WeakCallbackMethodDelegate(const LivenessBroker& info, 400 const void* self) { 401 // Callback is registered through a potential const Trace method but needs 402 // to be able to modify fields. See HandleWeak. 403 (const_cast
(static_cast
(self))->*method)(info); 404 } 405 406 template
407 static void HandleWeak(const LivenessBroker& info, const void* object) { 408 const PointerType* weak = static_cast
(object); 409 if (!info.IsHeapObjectAlive(weak->GetFromGC())) { 410 weak->ClearFromGC(); 411 } 412 } 413 414 template
415 void TraceImpl(const T* t) { 416 static_assert(sizeof(T), "Pointee type must be fully defined."); 417 static_assert(internal::IsGarbageCollectedOrMixinType
::value, 418 "T must be GarbageCollected or GarbageCollectedMixin type"); 419 if (!t) { 420 return; 421 } 422 Visit(t, TraceTrait
::GetTraceDescriptor(t)); 423 } 424 425 #if V8_ENABLE_CHECKS 426 void CheckObjectNotInConstruction(const void* address); 427 #endif // V8_ENABLE_CHECKS 428 429 template
431 friend class internal::BasicCrossThreadPersistent; 432 template
434 friend class internal::BasicPersistent; 435 friend class internal::ConservativeTracingVisitor; 436 friend class internal::VisitorBase; 437 }; 438 439 namespace internal { 440 441 class V8_EXPORT RootVisitor { 442 public: 443 explicit RootVisitor(Visitor::Key) {} 444 445 virtual ~RootVisitor() = default; 446 447 template
* = nullptr> 450 void Trace(const AnyStrongPersistentType& p) { 451 using PointeeType = typename AnyStrongPersistentType::PointeeType; 452 const void* object = Extract(p); 453 if (!object) { 454 return; 455 } 456 VisitRoot(object, TraceTrait
::GetTraceDescriptor(object), 457 p.Location()); 458 } 459 460 template
* = nullptr> 463 void Trace(const AnyWeakPersistentType& p) { 464 using PointeeType = typename AnyWeakPersistentType::PointeeType; 465 static_assert(!internal::IsAllocatedOnCompactableSpace
::value, 466 "Weak references to compactable objects are not allowed"); 467 const void* object = Extract(p); 468 if (!object) { 469 return; 470 } 471 VisitWeakRoot(object, TraceTrait
::GetTraceDescriptor(object), 472 &HandleWeak
, &p, p.Location()); 473 } 474 475 protected: 476 virtual void VisitRoot(const void*, TraceDescriptor, const SourceLocation&) {} 477 virtual void VisitWeakRoot(const void* self, TraceDescriptor, WeakCallback, 478 const void* weak_root, const SourceLocation&) {} 479 480 private: 481 template
482 static const void* Extract(AnyPersistentType& p) { 483 using PointeeType = typename AnyPersistentType::PointeeType; 484 static_assert(sizeof(PointeeType), 485 "Persistent's pointee type must be fully defined"); 486 static_assert(internal::IsGarbageCollectedOrMixinType
::value, 487 "Persistent's pointee type must be GarbageCollected or " 488 "GarbageCollectedMixin"); 489 return p.GetFromGC(); 490 } 491 492 template
493 static void HandleWeak(const LivenessBroker& info, const void* object) { 494 const PointerType* weak = static_cast
(object); 495 if (!info.IsHeapObjectAlive(weak->GetFromGC())) { 496 weak->ClearFromGC(); 497 } 498 } 499 }; 500 501 } // namespace internal 502 } // namespace cppgc 503 504 #endif // INCLUDE_CPPGC_VISITOR_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2026 MyWebUniversity.com ™