v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
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