v8 11.3.244 (node 20.3.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 Member<T>& member) {
72 const T* value = member.GetRawAtomic();
74 TraceImpl(value);
75 }
76
82 template <typename T>
83 void Trace(const WeakMember<T>& weak_member) {
84 static_assert(sizeof(T), "Pointee type must be fully defined.");
86 "T must be GarbageCollected or GarbageCollectedMixin type");
88 "Weak references to compactable objects are not allowed");
89
90 const T* value = weak_member.GetRawAtomic();
91
92 // Bailout assumes that WeakMember emits write barrier.
93 if (!value) {
94 return;
95 }
96
98 VisitWeak(value, TraceTrait<T>::GetTraceDescriptor(value),
99 &HandleWeak<WeakMember<T>>, &weak_member);
100 }
101
102#if defined(CPPGC_POINTER_COMPRESSION)
108 template <typename T>
109 void Trace(const subtle::UncompressedMember<T>& member) {
110 const T* value = member.GetRawAtomic();
111 CPPGC_DCHECK(value != kSentinelPointer);
112 TraceImpl(value);
113 }
114#endif // defined(CPPGC_POINTER_COMPRESSION)
115
122 template <typename T>
123 void Trace(const T& object) {
124#if V8_ENABLE_CHECKS
125 // This object is embedded in potentially multiple nested objects. The
126 // outermost object must not be in construction as such objects are (a) not
127 // processed immediately, and (b) only processed conservatively if not
128 // otherwise possible.
129 CheckObjectNotInConstruction(&object);
130#endif // V8_ENABLE_CHECKS
131 TraceTrait<T>::Trace(this, &object);
132 }
133
140 template <typename T, void (T::*method)(const LivenessBroker&)>
141 void RegisterWeakCallbackMethod(const T* object) {
142 RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>, object);
143 }
144
151 template <typename K, typename V>
152 void Trace(const EphemeronPair<K, V>& ephemeron_pair) {
153 TraceEphemeron(ephemeron_pair.key, &ephemeron_pair.value);
154 RegisterWeakCallbackMethod<EphemeronPair<K, V>,
156 &ephemeron_pair);
157 }
158
166 template <typename KeyType, typename ValueType>
167 void TraceEphemeron(const WeakMember<KeyType>& weak_member_key,
168 const Member<ValueType>* member_value) {
169 const KeyType* key = weak_member_key.GetRawAtomic();
170 if (!key) return;
171
172 // `value` must always be non-null.
173 CPPGC_DCHECK(member_value);
174 const ValueType* value = member_value->GetRawAtomic();
175 if (!value) return;
176
177 // KeyType and ValueType may refer to GarbageCollectedMixin.
178 TraceDescriptor value_desc =
181 const void* key_base_object_payload =
182 TraceTrait<KeyType>::GetTraceDescriptor(key).base_object_payload;
183 CPPGC_DCHECK(key_base_object_payload);
184
185 VisitEphemeron(key_base_object_payload, value, value_desc);
186 }
187
199 template <typename KeyType, typename ValueType>
200 void TraceEphemeron(const WeakMember<KeyType>& weak_member_key,
201 const ValueType* value) {
202 static_assert(!IsGarbageCollectedOrMixinTypeV<ValueType>,
203 "garbage-collected types must use WeakMember and Member");
204 const KeyType* key = weak_member_key.GetRawAtomic();
205 if (!key) return;
206
207 // `value` must always be non-null.
208 CPPGC_DCHECK(value);
209 TraceDescriptor value_desc =
211 // `value_desc.base_object_payload` must be null as this override is only
212 // taken for non-garbage-collected values.
214
215 // KeyType might be a GarbageCollectedMixin.
216 const void* key_base_object_payload =
217 TraceTrait<KeyType>::GetTraceDescriptor(key).base_object_payload;
218 CPPGC_DCHECK(key_base_object_payload);
219
220 VisitEphemeron(key_base_object_payload, value, value_desc);
221 }
222
228 template <typename T>
229 void TraceStrongly(const WeakMember<T>& weak_member) {
230 const T* value = weak_member.GetRawAtomic();
232 TraceImpl(value);
233 }
234
240 template <typename T>
241 void TraceStrongContainer(const T* object) {
242 TraceImpl(object);
243 }
244
253 template <typename T>
254 void TraceWeakContainer(const T* object, WeakCallback callback,
255 const void* callback_data) {
256 if (!object) return;
257 VisitWeakContainer(object, TraceTrait<T>::GetTraceDescriptor(object),
259 callback_data);
260 }
261
269 template <typename T>
270 void RegisterMovableReference(const T** slot) {
272 "Only references to objects allocated on compactable spaces "
273 "should be registered as movable slots.");
274 static_assert(!IsGarbageCollectedMixinTypeV<T>,
275 "Mixin types do not support compaction.");
276 HandleMovableReference(reinterpret_cast<const void**>(slot));
277 }
278
285 virtual void RegisterWeakCallback(WeakCallback callback, const void* data) {}
286
301 const void* parameter, TraceCallback callback, size_t deferred_size) {
302 // By default tracing is not deferred.
303 return false;
304 }
305
306 protected:
307 virtual void Visit(const void* self, TraceDescriptor) {}
308 virtual void VisitWeak(const void* self, TraceDescriptor, WeakCallback,
309 const void* weak_member) {}
310 virtual void VisitEphemeron(const void* key, const void* value,
311 TraceDescriptor value_desc) {}
312 virtual void VisitWeakContainer(const void* self, TraceDescriptor strong_desc,
313 TraceDescriptor weak_desc,
314 WeakCallback callback, const void* data) {}
315 virtual void HandleMovableReference(const void**) {}
316
317 private:
318 template <typename T, void (T::*method)(const LivenessBroker&)>
319 static void WeakCallbackMethodDelegate(const LivenessBroker& info,
320 const void* self) {
321 // Callback is registered through a potential const Trace method but needs
322 // to be able to modify fields. See HandleWeak.
323 (const_cast<T*>(static_cast<const T*>(self))->*method)(info);
324 }
325
326 template <typename PointerType>
327 static void HandleWeak(const LivenessBroker& info, const void* object) {
328 const PointerType* weak = static_cast<const PointerType*>(object);
329 auto* raw_ptr = weak->GetFromGC();
330 if (!info.IsHeapObjectAlive(raw_ptr)) {
331 weak->ClearFromGC();
332 }
333 }
334
335 template <typename T>
336 void TraceImpl(const T* t) {
337 static_assert(sizeof(T), "Pointee type must be fully defined.");
338 static_assert(internal::IsGarbageCollectedOrMixinType<T>::value,
339 "T must be GarbageCollected or GarbageCollectedMixin type");
340 if (!t) {
341 return;
342 }
343 Visit(t, TraceTrait<T>::GetTraceDescriptor(t));
344 }
345
346#if V8_ENABLE_CHECKS
347 void CheckObjectNotInConstruction(const void* address);
348#endif // V8_ENABLE_CHECKS
349
350 template <typename T, typename WeaknessPolicy, typename LocationPolicy,
351 typename CheckingPolicy>
353 template <typename T, typename WeaknessPolicy, typename LocationPolicy,
354 typename CheckingPolicy>
356 friend class internal::ConservativeTracingVisitor;
357 friend class internal::VisitorBase;
358};
359
360namespace internal {
361
363 public:
365
366 virtual ~RootVisitor() = default;
367
368 template <typename AnyStrongPersistentType,
369 std::enable_if_t<
370 AnyStrongPersistentType::IsStrongPersistent::value>* = nullptr>
371 void Trace(const AnyStrongPersistentType& p) {
372 using PointeeType = typename AnyStrongPersistentType::PointeeType;
373 const void* object = Extract(p);
374 if (!object) {
375 return;
376 }
377 VisitRoot(object, TraceTrait<PointeeType>::GetTraceDescriptor(object),
378 p.Location());
379 }
380
381 template <typename AnyWeakPersistentType,
382 std::enable_if_t<
383 !AnyWeakPersistentType::IsStrongPersistent::value>* = nullptr>
384 void Trace(const AnyWeakPersistentType& p) {
385 using PointeeType = typename AnyWeakPersistentType::PointeeType;
387 "Weak references to compactable objects are not allowed");
388 const void* object = Extract(p);
389 if (!object) {
390 return;
391 }
392 VisitWeakRoot(object, TraceTrait<PointeeType>::GetTraceDescriptor(object),
393 &HandleWeak<AnyWeakPersistentType>, &p, p.Location());
394 }
395
396 protected:
397 virtual void VisitRoot(const void*, TraceDescriptor, const SourceLocation&) {}
398 virtual void VisitWeakRoot(const void* self, TraceDescriptor, WeakCallback,
399 const void* weak_root, const SourceLocation&) {}
400
401 private:
402 template <typename AnyPersistentType>
403 static const void* Extract(AnyPersistentType& p) {
404 using PointeeType = typename AnyPersistentType::PointeeType;
405 static_assert(sizeof(PointeeType),
406 "Persistent's pointee type must be fully defined");
408 "Persistent's pointee type must be GarbageCollected or "
409 "GarbageCollectedMixin");
410 return p.GetFromGC();
411 }
412
413 template <typename PointerType>
414 static void HandleWeak(const LivenessBroker& info, const void* object) {
415 const PointerType* weak = static_cast<const PointerType*>(object);
416 auto* raw_ptr = weak->GetFromGC();
417 if (!info.IsHeapObjectAlive(raw_ptr)) {
418 weak->ClearFromGC();
419 }
420 }
421};
422
423} // namespace internal
424} // namespace cppgc
425
426#endif // INCLUDE_CPPGC_VISITOR_H_
bool IsHeapObjectAlive(const T *object) const
virtual V8_WARN_UNUSED_RESULT bool DeferTraceToMutatorThreadIfConcurrent(const void *parameter, TraceCallback callback, size_t deferred_size)
Definition visitor.h:300
void Trace(const WeakMember< T > &weak_member)
Definition visitor.h:83
void Trace(const EphemeronPair< K, V > &ephemeron_pair)
Definition visitor.h:152
void TraceStrongContainer(const T *object)
Definition visitor.h:241
void RegisterMovableReference(const T **slot)
Definition visitor.h:270
void Trace(const Member< T > &member)
Definition visitor.h:71
virtual void VisitEphemeron(const void *key, const void *value, TraceDescriptor value_desc)
Definition visitor.h:310
virtual ~Visitor()=default
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const ValueType *value)
Definition visitor.h:200
void Trace(const T &object)
Definition visitor.h:123
void RegisterWeakCallbackMethod(const T *object)
Definition visitor.h:141
virtual void VisitWeak(const void *self, TraceDescriptor, WeakCallback, const void *weak_member)
Definition visitor.h:308
void TraceWeakContainer(const T *object, WeakCallback callback, const void *callback_data)
Definition visitor.h:254
virtual void VisitWeakContainer(const void *self, TraceDescriptor strong_desc, TraceDescriptor weak_desc, WeakCallback callback, const void *data)
Definition visitor.h:312
virtual void HandleMovableReference(const void **)
Definition visitor.h:315
void TraceEphemeron(const WeakMember< KeyType > &weak_member_key, const Member< ValueType > *member_value)
Definition visitor.h:167
void TraceStrongly(const WeakMember< T > &weak_member)
Definition visitor.h:229
virtual void RegisterWeakCallback(WeakCallback callback, const void *data)
Definition visitor.h:285
virtual void Visit(const void *self, TraceDescriptor)
Definition visitor.h:307
virtual ~RootVisitor()=default
RootVisitor(Visitor::Key)
Definition visitor.h:364
void Trace(const AnyStrongPersistentType &p)
Definition visitor.h:371
void Trace(const AnyWeakPersistentType &p)
Definition visitor.h:384
virtual void VisitRoot(const void *, TraceDescriptor, const SourceLocation &)
Definition visitor.h:397
virtual void VisitWeakRoot(const void *self, TraceDescriptor, WeakCallback, const void *weak_root, const SourceLocation &)
Definition visitor.h:398
#define CPPGC_DCHECK(condition)
Definition logging.h:36
void(*)(Visitor *visitor, const void *object) TraceCallback
Definition trace-trait.h:38
void(*)(const LivenessBroker &, const void *) WeakCallback
Definition visitor.h:34
constexpr internal::SentinelPointer kSentinelPointer
WeakMember< K > key
const void * base_object_payload
Definition trace-trait.h:49
#define V8_EXPORT
Definition v8config.h:719
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:609