v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
visitor.h
Go to the documentation of this file.
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
14#include "cppgc/member.h"
17#include "cppgc/trace-trait.h"
18#include "cppgc/type-traits.h"
19
20namespace cppgc {
21
22namespace internal {
23template <typename T, typename WeaknessPolicy, typename LocationPolicy,
24 typename CheckingPolicy>
25class BasicCrossThreadPersistent;
26template <typename T, typename WeaknessPolicy, typename LocationPolicy,
27 typename CheckingPolicy>
28class BasicPersistent;
29class ConservativeTracingVisitor;
30class VisitorBase;
31class VisitorFactory;
32} // namespace internal
33
34using WeakCallback = void (*)(const LivenessBroker&, const void*);
35
54 public:
55 class Key {
56 private:
57 Key() = default;
58 friend class internal::VisitorFactory;
59 };
60
61 explicit Visitor(Key) {}
62
63 virtual ~Visitor() = default;
64
70 template <typename T>
71 void Trace(const T* t) {
72 static_assert(sizeof(T), "Pointee type must be fully defined.");
74 "T must be GarbageCollected or GarbageCollectedMixin type");
75 if (!t) {
76 return;
77 }
79 }
80
86 template <typename T>
87 void Trace(const Member<T>& member) {
88 const T* value = member.GetRawAtomic();
90 Trace(value);
91 }
92
98 template <typename T>
99 void Trace(const WeakMember<T>& weak_member) {
100 static_assert(sizeof(T), "Pointee type must be fully defined.");
102 "T must be GarbageCollected or GarbageCollectedMixin type");
104 "Weak references to compactable objects are not allowed");
105
106 const T* value = weak_member.GetRawAtomic();
107
108 // Bailout assumes that WeakMember emits write barrier.
109 if (!value) {
110 return;
111 }
112
114 VisitWeak(value, TraceTrait<T>::GetTraceDescriptor(value),
115 &HandleWeak<WeakMember<T>>, &weak_member);
116 }
117
124 template <typename T>
125 void Trace(const T& object) {
126#if V8_ENABLE_CHECKS
127 // This object is embedded in potentially multiple nested objects. The
128 // outermost object must not be in construction as such objects are (a) not
129 // processed immediately, and (b) only processed conservatively if not
130 // otherwise possible.
131 CheckObjectNotInConstruction(&object);
132#endif // V8_ENABLE_CHECKS
133 TraceTrait<T>::Trace(this, &object);
134 }
135
142 template <typename T, void (T::*method)(const LivenessBroker&)>
143 void RegisterWeakCallbackMethod(const T* object) {
144 RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>, object);
145 }
146
153 template <typename K, typename V>
154 void Trace(const EphemeronPair<K, V>& ephemeron_pair) {
155 TraceEphemeron(ephemeron_pair.key, &ephemeron_pair.value);
156 RegisterWeakCallbackMethod<EphemeronPair<K, V>,
158 &ephemeron_pair);
159 }
160
168 template <typename KeyType, typename ValueType>
169 void TraceEphemeron(const WeakMember<KeyType>& weak_member_key,
170 const Member<ValueType>* member_value) {
171 const KeyType* key = weak_member_key.GetRawAtomic();
172 if (!key) return;
173
174 // `value` must always be non-null.
175 CPPGC_DCHECK(member_value);
176 const ValueType* value = member_value->GetRawAtomic();
177 if (!value) return;
178
179 // KeyType and ValueType may refer to GarbageCollectedMixin.
180 TraceDescriptor value_desc =
183 const void* key_base_object_payload =
184 TraceTrait<KeyType>::GetTraceDescriptor(key).base_object_payload;
185 CPPGC_DCHECK(key_base_object_payload);
186
187 VisitEphemeron(key_base_object_payload, value, value_desc);
188 }
189
201 template <typename KeyType, typename ValueType>
202 void TraceEphemeron(const WeakMember<KeyType>& weak_member_key,
203 const ValueType* value) {
204 static_assert(!IsGarbageCollectedOrMixinTypeV<ValueType>,
205 "garbage-collected types must use WeakMember and Member");
206 const KeyType* key = weak_member_key.GetRawAtomic();
207 if (!key) return;
208
209 // `value` must always be non-null.
210 CPPGC_DCHECK(value);
211 TraceDescriptor value_desc =
213 // `value_desc.base_object_payload` must be null as this override is only
214 // taken for non-garbage-collected values.
216
217 // KeyType might be a GarbageCollectedMixin.
218 const void* key_base_object_payload =
219 TraceTrait<KeyType>::GetTraceDescriptor(key).base_object_payload;
220 CPPGC_DCHECK(key_base_object_payload);
221
222 VisitEphemeron(key_base_object_payload, value, value_desc);
223 }
224
230 template <typename T>
231 void TraceStrongly(const WeakMember<T>& weak_member) {
232 const T* value = weak_member.GetRawAtomic();
234 Trace(value);
235 }
236
244 template <typename T>
245 void TraceWeakContainer(const T* object, WeakCallback callback,
246 const void* data) {
247 if (!object) return;
248 VisitWeakContainer(object, TraceTrait<T>::GetTraceDescriptor(object),
250 data);
251 }
252
259 template <typename T>
260 void RegisterMovableReference(const T** slot) {
262 "Only references to objects allocated on compactable spaces "
263 "should be registered as movable slots.");
264 static_assert(!IsGarbageCollectedMixinTypeV<T>,
265 "Mixin types do not support compaction.");
266 HandleMovableReference(reinterpret_cast<const void**>(slot));
267 }
268
275 virtual void RegisterWeakCallback(WeakCallback callback, const void* data) {}
276
291 const void* parameter, TraceCallback callback, size_t deferred_size) {
292 // By default tracing is not deferred.
293 return false;
294 }
295
296 protected:
297 virtual void Visit(const void* self, TraceDescriptor) {}
298 virtual void VisitWeak(const void* self, TraceDescriptor, WeakCallback,
299 const void* weak_member) {}
300 virtual void VisitRoot(const void*, TraceDescriptor, const SourceLocation&) {}
301 virtual void VisitWeakRoot(const void* self, TraceDescriptor, WeakCallback,
302 const void* weak_root, const SourceLocation&) {}
303 virtual void VisitEphemeron(const void* key, const void* value,
304 TraceDescriptor value_desc) {}
305 virtual void VisitWeakContainer(const void* self, TraceDescriptor strong_desc,
306 TraceDescriptor weak_desc,
307 WeakCallback callback, const void* data) {}
308 virtual void HandleMovableReference(const void**) {}
309
310 private:
311 template <typename T, void (T::*method)(const LivenessBroker&)>
312 static void WeakCallbackMethodDelegate(const LivenessBroker& info,
313 const void* self) {
314 // Callback is registered through a potential const Trace method but needs
315 // to be able to modify fields. See HandleWeak.
316 (const_cast<T*>(static_cast<const T*>(self))->*method)(info);
317 }
318
319 template <typename PointerType>
320 static void HandleWeak(const LivenessBroker& info, const void* object) {
321 const PointerType* weak = static_cast<const PointerType*>(object);
322 auto* raw_ptr = weak->GetFromGC();
323 // Sentinel values are preserved for weak pointers.
324 if (raw_ptr == kSentinelPointer) return;
325 if (!info.IsHeapObjectAlive(raw_ptr)) {
326 weak->ClearFromGC();
327 }
328 }
329
330 template <typename Persistent,
331 std::enable_if_t<Persistent::IsStrongPersistent::value>* = nullptr>
332 void TraceRoot(const Persistent& p, const SourceLocation& loc) {
333 using PointeeType = typename Persistent::PointeeType;
334 static_assert(sizeof(PointeeType),
335 "Persistent's pointee type must be fully defined");
336 static_assert(internal::IsGarbageCollectedOrMixinType<PointeeType>::value,
337 "Persistent's pointee type must be GarbageCollected or "
338 "GarbageCollectedMixin");
339 auto* ptr = p.GetFromGC();
340 if (!ptr) {
341 return;
342 }
343 VisitRoot(ptr, TraceTrait<PointeeType>::GetTraceDescriptor(ptr), loc);
344 }
345
346 template <
347 typename WeakPersistent,
348 std::enable_if_t<!WeakPersistent::IsStrongPersistent::value>* = nullptr>
349 void TraceRoot(const WeakPersistent& p, const SourceLocation& loc) {
350 using PointeeType = typename WeakPersistent::PointeeType;
351 static_assert(sizeof(PointeeType),
352 "Persistent's pointee type must be fully defined");
353 static_assert(internal::IsGarbageCollectedOrMixinType<PointeeType>::value,
354 "Persistent's pointee type must be GarbageCollected or "
355 "GarbageCollectedMixin");
356 static_assert(!internal::IsAllocatedOnCompactableSpace<PointeeType>::value,
357 "Weak references to compactable objects are not allowed");
358 auto* ptr = p.GetFromGC();
359 VisitWeakRoot(ptr, TraceTrait<PointeeType>::GetTraceDescriptor(ptr),
360 &HandleWeak<WeakPersistent>, &p, loc);
361 }
362
363#if V8_ENABLE_CHECKS
364 void CheckObjectNotInConstruction(const void* address);
365#endif // V8_ENABLE_CHECKS
366
367 template <typename T, typename WeaknessPolicy, typename LocationPolicy,
368 typename CheckingPolicy>
370 template <typename T, typename WeaknessPolicy, typename LocationPolicy,
371 typename CheckingPolicy>
373 friend class internal::ConservativeTracingVisitor;
374 friend class internal::VisitorBase;
375};
376
377} // namespace cppgc
378
379#endif // INCLUDE_CPPGC_VISITOR_H_
virtual V8_WARN_UNUSED_RESULT bool DeferTraceToMutatorThreadIfConcurrent(const void *parameter, TraceCallback callback, size_t deferred_size)
Definition visitor.h:290
void Trace(const WeakMember< T > &weak_member)
Definition visitor.h:99
void Trace(const EphemeronPair< K, V > &ephemeron_pair)
Definition visitor.h:154
void RegisterMovableReference(const T **slot)
Definition visitor.h:260
void TraceWeakContainer(const T *object, WeakCallback callback, const void *data)
Definition visitor.h:245
void Trace(const Member< T > &member)
Definition visitor.h:87
virtual void VisitEphemeron(const void *key, const void *value, TraceDescriptor value_desc)
Definition visitor.h:303
virtual ~Visitor()=default
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const ValueType *value)
Definition visitor.h:202
void Trace(const T &object)
Definition visitor.h:125
virtual void VisitRoot(const void *, TraceDescriptor, const SourceLocation &)
Definition visitor.h:300
void RegisterWeakCallbackMethod(const T *object)
Definition visitor.h:143
virtual void VisitWeak(const void *self, TraceDescriptor, WeakCallback, const void *weak_member)
Definition visitor.h:298
void Trace(const T *t)
Definition visitor.h:71
virtual void VisitWeakRoot(const void *self, TraceDescriptor, WeakCallback, const void *weak_root, const SourceLocation &)
Definition visitor.h:301
virtual void VisitWeakContainer(const void *self, TraceDescriptor strong_desc, TraceDescriptor weak_desc, WeakCallback callback, const void *data)
Definition visitor.h:305
virtual void HandleMovableReference(const void **)
Definition visitor.h:308
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const Member< ValueType > *member_value)
Definition visitor.h:169
void TraceStrongly(const WeakMember< T > &weak_member)
Definition visitor.h:231
virtual void RegisterWeakCallback(WeakCallback callback, const void *data)
Definition visitor.h:275
virtual void Visit(const void *self, TraceDescriptor)
Definition visitor.h:297
#define CPPGC_DCHECK(condition)
Definition logging.h:36
internal::BasicPersistent< T, internal::WeakPersistentPolicy > WeakPersistent
Definition persistent.h:366
void(*)(Visitor *visitor, const void *object) TraceCallback
Definition trace-trait.h:34
void(*)(const LivenessBroker &, const void *) WeakCallback
Definition visitor.h:34
constexpr internal::SentinelPointer kSentinelPointer
internal::BasicPersistent< T, internal::StrongPersistentPolicy > Persistent
Definition persistent.h:356
WeakMember< K > key
const void * base_object_payload
Definition trace-trait.h:45
#define V8_EXPORT
Definition v8config.h:578
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:499