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