5#ifndef INCLUDE_CPPGC_VISITOR_H_
6#define INCLUDE_CPPGC_VISITOR_H_
26template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
27 typename CheckingPolicy>
29template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
30 typename CheckingPolicy>
43template <
typename K,
typename V>
52 if (!
broker.IsHeapObjectAlive(
key)) value =
nullptr;
104 template <
typename T>
106 static_assert(
sizeof(
T),
"Pointee type must be fully defined.");
108 "T must be GarbageCollected or GarbageCollectedMixin type");
110 "Weak references to compactable objects are not allowed");
124#if defined(CPPGC_POINTER_COMPRESSION)
130 template <
typename T>
138 template <
typename T>
140 static_assert(
sizeof(
T),
"Pointee type must be fully defined.");
142 "T must be GarbageCollected or GarbageCollectedMixin type");
143 VisitMultipleUncompressedMember(
start, len,
147 template <
typename T,
148 std::enable_if_t<!std::is_same_v<
151 static_assert(
sizeof(
T),
"Pointee type must be fully defined.");
153 "T must be GarbageCollected or GarbageCollectedMixin type");
154#if defined(CPPGC_POINTER_COMPRESSION)
155 static_assert(std::is_same_v<Member<T>, subtle::CompressedMember<T>>,
156 "Member and CompressedMember must be the same.");
157 VisitMultipleCompressedMember(
start, len,
168 template <
typename T>
175 CheckObjectNotInConstruction(&
object);
180 template <
typename T>
187 CheckObjectNotInConstruction(
start);
189 for (
size_t i = 0;
i < len; ++
i) {
190 const T*
object = &
start[
i];
191 if constexpr (std::is_polymorphic_v<T>) {
194 if (*
reinterpret_cast<const uintptr_t*
>(
object) == 0)
continue;
206 template <
typename T,
void (T::*method)(const LivenessBroker&)>
208 RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>,
object);
217 template <
typename K,
typename V>
219 TraceEphemeron(ephemeron_pair.
key, &ephemeron_pair.
value);
220 RegisterWeakCallbackMethod<EphemeronPair<K, V>,
232 template <
typename KeyType,
typename ValueType>
240 const ValueType* value = member_value->GetRawAtomic();
247 const void* key_base_object_payload =
251 VisitEphemeron(key_base_object_payload, value, value_desc);
265 template <
typename KeyType,
typename ValueType>
267 const ValueType* value) {
268 static_assert(!IsGarbageCollectedOrMixinTypeV<ValueType>,
269 "garbage-collected types must use WeakMember and Member");
282 const void* key_base_object_payload =
286 VisitEphemeron(key_base_object_payload, value, value_desc);
294 template <
typename T>
306 template <
typename T>
319 template <
typename T>
321 const void* callback_data) {
335 template <
typename T>
338 "Only references to objects allocated on compactable spaces "
339 "should be registered as movable slots.");
340 static_assert(!IsGarbageCollectedMixinTypeV<T>,
341 "Mixin types do not support compaction.");
342 HandleMovableReference(
reinterpret_cast<const void**
>(slot));
375 const void* weak_member) {}
384 const void*
start,
size_t len,
387 const char* it =
static_cast<const char*
>(
start);
388 const char*
end = it + len * internal::kSizeOfUncompressedMember;
389 for (; it <
end; it += internal::kSizeOfUncompressedMember) {
392 if (!
object)
continue;
394 Visit(
object, get_trace_descriptor(
object));
398#if defined(CPPGC_POINTER_COMPRESSION)
399 virtual void VisitMultipleCompressedMember(
400 const void*
start,
size_t len,
403 const char* it =
static_cast<const char*
>(
start);
404 const char*
end = it + len * internal::kSizeofCompressedMember;
405 for (; it <
end; it += internal::kSizeofCompressedMember) {
406 const auto* current =
407 reinterpret_cast<const internal::CompressedPointer*
>(it);
408 const void*
object = current->LoadAtomic();
409 if (!
object)
continue;
411 Visit(
object, get_trace_descriptor(
object));
417 template <
typename T,
void (T::*method)(const LivenessBroker&)>
422 (
const_cast<T*
>(
static_cast<const T*
>(self))->*
method)(info);
425 template <
typename Po
interType>
427 const PointerType* weak =
static_cast<const PointerType*
>(object);
428 if (!info.IsHeapObjectAlive(weak->GetFromGC())) {
433 template <
typename T>
435 static_assert(
sizeof(
T),
"Pointee type must be fully defined.");
437 "T must be GarbageCollected or GarbageCollectedMixin type");
445 void CheckObjectNotInConstruction(
const void* address);
448 template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
449 typename CheckingPolicy>
451 template <
typename T,
typename WeaknessPolicy,
typename LocationPolicy,
452 typename CheckingPolicy>
458template <
typename K,
typename V>
471 template <
typename AnyStrongPersistentType,
473 AnyStrongPersistentType::IsStrongPersistent::value>* =
nullptr>
474 void Trace(
const AnyStrongPersistentType& p) {
475 using PointeeType =
typename AnyStrongPersistentType::PointeeType;
476 const void*
object = Extract(p);
484 template <
typename AnyWeakPersistentType,
486 !AnyWeakPersistentType::IsStrongPersistent::value>* =
nullptr>
487 void Trace(
const AnyWeakPersistentType& p) {
488 using PointeeType =
typename AnyWeakPersistentType::PointeeType;
490 "Weak references to compactable objects are not allowed");
491 const void*
object = Extract(p);
496 &HandleWeak<AnyWeakPersistentType>, &p, p.Location());
505 template <
typename AnyPersistentType>
506 static const void*
Extract(AnyPersistentType& p) {
507 using PointeeType =
typename AnyPersistentType::PointeeType;
508 static_assert(
sizeof(PointeeType),
509 "Persistent's pointee type must be fully defined");
511 "Persistent's pointee type must be GarbageCollected or "
512 "GarbageCollectedMixin");
513 return p.GetFromGC();
516 template <
typename Po
interType>
518 const PointerType* weak =
static_cast<const PointerType*
>(object);
519 if (!info.IsHeapObjectAlive(weak->GetFromGC())) {
void Trace(const Member< T > &member)
void TraceWeakContainer(const T *object, WeakCallback callback, const void *callback_data)
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const Member< ValueType > *member_value)
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const ValueType *value)
void TraceMultiple(const Member< T > *start, size_t len)
virtual void Visit(const void *self, TraceDescriptor)
virtual void VisitEphemeron(const void *key, const void *value, TraceDescriptor value_desc)
virtual V8_WARN_UNUSED_RESULT bool DeferTraceToMutatorThreadIfConcurrent(const void *parameter, TraceCallback callback, size_t deferred_size)
void Trace(const T &object)
void TraceStrongly(const WeakMember< T > &weak_member)
static void WeakCallbackMethodDelegate(const LivenessBroker &info, const void *self)
virtual void RegisterWeakCallback(WeakCallback callback, const void *data)
virtual void VisitWeak(const void *self, TraceDescriptor, WeakCallback, const void *weak_member)
void RegisterMovableReference(const T **slot)
virtual void HandleMovableReference(const void **)
void TraceImpl(const T *t)
virtual void VisitMultipleUncompressedMember(const void *start, size_t len, TraceDescriptorCallback get_trace_descriptor)
virtual void VisitWeakContainer(const void *self, TraceDescriptor strong_desc, TraceDescriptor weak_desc, WeakCallback callback, const void *data)
void TraceMultiple(const T *start, size_t len)
static void HandleWeak(const LivenessBroker &info, const void *object)
void RegisterWeakCallbackMethod(const T *object)
void TraceStrongContainer(const T *object)
void Trace(const WeakMember< T > &weak_member)
void Trace(const EphemeronPair< K, V > &ephemeron_pair)
virtual ~Visitor()=default
void TraceMultiple(const subtle::UncompressedMember< T > *start, size_t len)
V8_INLINE const T * GetRawAtomic() const
V8_INLINE const void * LoadAtomic() const
static void HandleWeak(const LivenessBroker &info, const void *object)
virtual void VisitRoot(const void *, TraceDescriptor, const SourceLocation &)
virtual ~RootVisitor()=default
static const void * Extract(AnyPersistentType &p)
RootVisitor(Visitor::Key)
virtual void VisitWeakRoot(const void *self, TraceDescriptor, WeakCallback, const void *weak_root, const SourceLocation &)
void Trace(const AnyWeakPersistentType &p)
void Trace(const AnyStrongPersistentType &p)
#define CPPGC_DCHECK(condition)
constexpr internal::SentinelPointer kSentinelPointer
void(*)(const LivenessBroker &, const void *) WeakCallback
TraceDescriptor(*)(const void *address) TraceDescriptorCallback
void(*)(Visitor *visitor, const void *object) TraceCallback
EphemeronPair(K *k, V *v)
void ClearValueIfKeyIsDead(const LivenessBroker &broker)
void Trace(Visitor *visitor) const
const void * base_object_payload
#define V8_WARN_UNUSED_RESULT
std::unique_ptr< ValueMirror > key