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_TRACE_TRAIT_H_
6 #define INCLUDE_CPPGC_TRACE_TRAIT_H_
7 
8 #include <type_traits>
9 
10 #include "cppgc/type-traits.h"
11 #include "v8config.h"  // NOLINT(build/include_directory)
12 
13 namespace cppgc {
14 
15 class Visitor;
16 
17 namespace internal {
18 
19 class RootVisitor;
20 
21 using TraceRootCallback = void (*)(RootVisitor&, const void* object);
22 
23 // Implementation of the default TraceTrait handling GarbageCollected and
24 // GarbageCollectedMixin.
25 template <typename T,
26           bool =
27               IsGarbageCollectedMixinTypeV<typename std::remove_const<T>::type>>
28 struct TraceTraitImpl;
29 
30 }  // namespace internal
31 
32 /**
33  * Callback for invoking tracing on a given object.
34  *
35  * \param visitor The visitor to dispatch to.
36  * \param object The object to invoke tracing on.
37  */
38 using TraceCallback = void (*)(Visitor* visitor, const void* object);
39 
40 /**
41  * Describes how to trace an object, i.e., how to visit all Oilpan-relevant
42  * fields of an object.
43  */
44 struct TraceDescriptor {
45   /**
46    * Adjusted base pointer, i.e., the pointer to the class inheriting directly
47    * from GarbageCollected, of the object that is being traced.
48    */
49   const void* base_object_payload;
50   /**
51    * Callback for tracing the object.
52    */
53   TraceCallback callback;
54 };
55 
56 namespace internal {
57 
58 struct V8_EXPORT TraceTraitFromInnerAddressImpl {
59   static TraceDescriptor GetTraceDescriptor(const void* address);
60 };
61 
62 /**
63  * Trait specifying how the garbage collector processes an object of type T.
64  *
65  * Advanced users may override handling by creating a specialization for their
66  * type.
67  */
68 template <typename T>
69 struct TraceTraitBase {
70   static_assert(internal::IsTraceableV<T>, "T must have a Trace() method");
71 
72   /**
73    * Accessor for retrieving a TraceDescriptor to process an object of type T.
74    *
75    * \param self The object to be processed.
76    * \returns a TraceDescriptor to process the object.
77    */
GetTraceDescriptorcppgc::internal::TraceTraitBase78   static TraceDescriptor GetTraceDescriptor(const void* self) {
79     return internal::TraceTraitImpl<T>::GetTraceDescriptor(
80         static_cast<const T*>(self));
81   }
82 
83   /**
84    * Function invoking the tracing for an object of type T.
85    *
86    * \param visitor The visitor to dispatch to.
87    * \param self The object to invoke tracing on.
88    */
Tracecppgc::internal::TraceTraitBase89   static void Trace(Visitor* visitor, const void* self) {
90     static_cast<const T*>(self)->Trace(visitor);
91   }
92 };
93 
94 }  // namespace internal
95 
96 template <typename T>
97 struct TraceTrait : public internal::TraceTraitBase<T> {};
98 
99 namespace internal {
100 
101 template <typename T>
102 struct TraceTraitImpl<T, false> {
103   static_assert(IsGarbageCollectedTypeV<T>,
104                 "T must be of type GarbageCollected or GarbageCollectedMixin");
GetTraceDescriptorcppgc::internal::TraceTraitImpl105   static TraceDescriptor GetTraceDescriptor(const void* self) {
106     return {self, TraceTrait<T>::Trace};
107   }
108 };
109 
110 template <typename T>
111 struct TraceTraitImpl<T, true> {
GetTraceDescriptorcppgc::internal::TraceTraitImpl112   static TraceDescriptor GetTraceDescriptor(const void* self) {
113     return internal::TraceTraitFromInnerAddressImpl::GetTraceDescriptor(self);
114   }
115 };
116 
117 }  // namespace internal
118 }  // namespace cppgc
119 
120 #endif  // INCLUDE_CPPGC_TRACE_TRAIT_H_
121