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