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 13namespace cppgc { 14 15class Visitor; 16 17namespace internal { 18 19class RootVisitor; 20 21using TraceRootCallback = void (*)(RootVisitor&, const void* object); 22 23// Implementation of the default TraceTrait handling GarbageCollected and 24// GarbageCollectedMixin. 25template <typename T, 26 bool = 27 IsGarbageCollectedMixinTypeV<typename std::remove_const<T>::type>> 28struct 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 */ 38using 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 */ 44struct 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 56namespace internal { 57 58struct 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 */ 68template <typename T> 69struct 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 */ 78 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 */ 89 static void Trace(Visitor* visitor, const void* self) { 90 static_cast<const T*>(self)->Trace(visitor); 91 } 92}; 93 94} // namespace internal 95 96template <typename T> 97struct TraceTrait : public internal::TraceTraitBase<T> {}; 98 99namespace internal { 100 101template <typename T> 102struct TraceTraitImpl<T, false> { 103 static_assert(IsGarbageCollectedTypeV<T>, 104 "T must be of type GarbageCollected or GarbageCollectedMixin"); 105 static TraceDescriptor GetTraceDescriptor(const void* self) { 106 return {self, TraceTrait<T>::Trace}; 107 } 108}; 109 110template <typename T> 111struct TraceTraitImpl<T, true> { 112 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