v8 11.3.244 (node 20.3.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 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