5#ifndef INCLUDE_CPPGC_VISITOR_H_
6#define INCLUDE_CPPGC_VISITOR_H_
26template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
27 typename CheckingPolicy>
28class BasicCrossThreadPersistent;
29template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
30 typename CheckingPolicy>
32class ConservativeTracingVisitor;
61 friend class internal::VisitorFactory;
75 const T* value = member.GetRawAtomic();
87 static_assert(
sizeof(T),
"Pointee type must be fully defined.");
89 "T must be GarbageCollected or GarbageCollectedMixin type");
91 "Weak references to compactable objects are not allowed");
93 const T* value = weak_member.GetRawAtomic();
105#if defined(CPPGC_POINTER_COMPRESSION)
111 template <
typename T>
113 const T* value = member.GetRawAtomic();
119 template <
typename T>
121 static_assert(
sizeof(T),
"Pointee type must be fully defined.");
123 "T must be GarbageCollected or GarbageCollectedMixin type");
124 VisitMultipleUncompressedMember(start, len,
128 template <
typename T,
129 std::enable_if_t<!std::is_same_v<
132 static_assert(
sizeof(T),
"Pointee type must be fully defined.");
134 "T must be GarbageCollected or GarbageCollectedMixin type");
135#if defined(CPPGC_POINTER_COMPRESSION)
136 static_assert(std::is_same_v<Member<T>, subtle::CompressedMember<T>>,
137 "Member and CompressedMember must be the same.");
138 VisitMultipleCompressedMember(start, len,
149 template <
typename T>
156 CheckObjectNotInConstruction(&
object);
161 template <
typename T>
168 CheckObjectNotInConstruction(start);
170 for (
size_t i = 0; i < len; ++i) {
171 const T*
object = &start[i];
172 if constexpr (std::is_polymorphic_v<T>) {
175 if (*
reinterpret_cast<const uintptr_t*
>(
object) == 0)
continue;
187 template <
typename T,
void (T::*method)(const LivenessBroker&)>
189 RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>,
object);
198 template <
typename K,
typename V>
200 TraceEphemeron(ephemeron_pair.
key, &ephemeron_pair.
value);
201 RegisterWeakCallbackMethod<EphemeronPair<K, V>,
213 template <
typename KeyType,
typename ValueType>
216 const KeyType* key = weak_member_key.GetRawAtomic();
221 const ValueType* value = member_value->GetRawAtomic();
228 const void* key_base_object_payload =
232 VisitEphemeron(key_base_object_payload, value, value_desc);
246 template <
typename KeyType,
typename ValueType>
248 const ValueType* value) {
249 static_assert(!IsGarbageCollectedOrMixinTypeV<ValueType>,
250 "garbage-collected types must use WeakMember and Member");
251 const KeyType* key = weak_member_key.GetRawAtomic();
263 const void* key_base_object_payload =
267 VisitEphemeron(key_base_object_payload, value, value_desc);
275 template <
typename T>
277 const T* value = weak_member.GetRawAtomic();
287 template <
typename T>
300 template <
typename T>
302 const void* callback_data) {
316 template <
typename T>
319 "Only references to objects allocated on compactable spaces "
320 "should be registered as movable slots.");
321 static_assert(!IsGarbageCollectedMixinTypeV<T>,
322 "Mixin types do not support compaction.");
323 HandleMovableReference(
reinterpret_cast<const void**
>(slot));
348 const void* parameter,
TraceCallback callback,
size_t deferred_size) {
356 const void* weak_member) {}
365 const void* start,
size_t len,
368 const char* it =
static_cast<const char*
>(start);
369 const char* end = it + len * internal::kSizeOfUncompressedMember;
370 for (; it < end; it += internal::kSizeOfUncompressedMember) {
373 if (!
object)
continue;
375 Visit(
object, get_trace_descriptor(
object));
379#if defined(CPPGC_POINTER_COMPRESSION)
380 virtual void VisitMultipleCompressedMember(
381 const void* start,
size_t len,
384 const char* it =
static_cast<const char*
>(start);
385 const char* end = it + len * internal::kSizeofCompressedMember;
386 for (; it < end; it += internal::kSizeofCompressedMember) {
387 const auto* current =
388 reinterpret_cast<const internal::CompressedPointer*
>(it);
389 const void*
object = current->LoadAtomic();
390 if (!
object)
continue;
392 Visit(
object, get_trace_descriptor(
object));
398 template <
typename T,
void (T::*method)(const LivenessBroker&)>
399 static void WeakCallbackMethodDelegate(
const LivenessBroker& info,
403 (
const_cast<T*
>(
static_cast<const T*
>(self))->*method)(info);
406 template <
typename Po
interType>
407 static void HandleWeak(
const LivenessBroker& info,
const void*
object) {
408 const PointerType* weak =
static_cast<const PointerType*
>(object);
409 if (!info.IsHeapObjectAlive(weak->GetFromGC())) {
414 template <
typename T>
415 void TraceImpl(
const T* t) {
416 static_assert(
sizeof(T),
"Pointee type must be fully defined.");
417 static_assert(internal::IsGarbageCollectedOrMixinType<T>::value,
418 "T must be GarbageCollected or GarbageCollectedMixin type");
422 Visit(t, TraceTrait<T>::GetTraceDescriptor(t));
426 void CheckObjectNotInConstruction(
const void* address);
429 template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
430 typename CheckingPolicy>
432 template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
433 typename CheckingPolicy>
435 friend class internal::ConservativeTracingVisitor;
436 friend class internal::VisitorBase;
447 template <
typename AnyStrongPersistentType,
449 AnyStrongPersistentType::IsStrongPersistent::value>* =
nullptr>
450 void Trace(
const AnyStrongPersistentType& p) {
451 using PointeeType =
typename AnyStrongPersistentType::PointeeType;
452 const void*
object = Extract(p);
460 template <
typename AnyWeakPersistentType,
462 !AnyWeakPersistentType::IsStrongPersistent::value>* =
nullptr>
463 void Trace(
const AnyWeakPersistentType& p) {
464 using PointeeType =
typename AnyWeakPersistentType::PointeeType;
466 "Weak references to compactable objects are not allowed");
467 const void*
object = Extract(p);
472 &HandleWeak<AnyWeakPersistentType>, &p, p.Location());
481 template <
typename AnyPersistentType>
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");
487 "Persistent's pointee type must be GarbageCollected or "
488 "GarbageCollectedMixin");
489 return p.GetFromGC();
492 template <
typename Po
interType>
493 static void HandleWeak(
const LivenessBroker& info,
const void*
object) {
494 const PointerType* weak =
static_cast<const PointerType*
>(object);
bool IsHeapObjectAlive(const T *object) const
virtual V8_WARN_UNUSED_RESULT bool DeferTraceToMutatorThreadIfConcurrent(const void *parameter, TraceCallback callback, size_t deferred_size)
void TraceMultiple(const Member< T > *start, size_t len)
void Trace(const WeakMember< T > &weak_member)
void Trace(const EphemeronPair< K, V > &ephemeron_pair)
void TraceStrongContainer(const T *object)
void RegisterMovableReference(const T **slot)
void Trace(const Member< T > &member)
virtual void VisitEphemeron(const void *key, const void *value, TraceDescriptor value_desc)
virtual void VisitMultipleUncompressedMember(const void *start, size_t len, TraceDescriptorCallback get_trace_descriptor)
virtual ~Visitor()=default
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const ValueType *value)
void Trace(const T &object)
void TraceMultiple(const T *start, size_t len)
void RegisterWeakCallbackMethod(const T *object)
virtual void VisitWeak(const void *self, TraceDescriptor, WeakCallback, const void *weak_member)
void TraceWeakContainer(const T *object, WeakCallback callback, const void *callback_data)
virtual void VisitWeakContainer(const void *self, TraceDescriptor strong_desc, TraceDescriptor weak_desc, WeakCallback callback, const void *data)
virtual void HandleMovableReference(const void **)
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const Member< ValueType > *member_value)
void TraceStrongly(const WeakMember< T > &weak_member)
virtual void RegisterWeakCallback(WeakCallback callback, const void *data)
void TraceMultiple(const subtle::UncompressedMember< T > *start, size_t len)
virtual void Visit(const void *self, TraceDescriptor)
V8_INLINE const void * LoadAtomic() const
virtual ~RootVisitor()=default
RootVisitor(Visitor::Key)
void Trace(const AnyStrongPersistentType &p)
void Trace(const AnyWeakPersistentType &p)
virtual void VisitRoot(const void *, TraceDescriptor, const SourceLocation &)
virtual void VisitWeakRoot(const void *self, TraceDescriptor, WeakCallback, const void *weak_root, const SourceLocation &)
#define CPPGC_DCHECK(condition)
TraceDescriptor(*)(const void *address) TraceDescriptorCallback
void(*)(Visitor *visitor, const void *object) TraceCallback
void(*)(const LivenessBroker &, const void *) WeakCallback
constexpr internal::SentinelPointer kSentinelPointer
const void * base_object_payload
#define V8_WARN_UNUSED_RESULT