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_LIVENESS_BROKER_H_ 6 #define INCLUDE_CPPGC_LIVENESS_BROKER_H_ 7 8 #include "cppgc/heap.h" 9 #include "cppgc/member.h" 10 #include "cppgc/trace-trait.h" 11 #include "v8config.h" // NOLINT(build/include_directory) 12 13 namespace cppgc { 14 15 namespace internal { 16 class LivenessBrokerFactory; 17 } // namespace internal 18 19 /** 20 * The broker is passed to weak callbacks to allow (temporarily) querying 21 * the liveness state of an object. References to non-live objects must be 22 * cleared when `IsHeapObjectAlive()` returns false. 23 * 24 * \code 25 * class GCedWithCustomWeakCallback final 26 * : public GarbageCollected<GCedWithCustomWeakCallback> { 27 * public: 28 * UntracedMember<Bar> bar; 29 * 30 * void CustomWeakCallbackMethod(const LivenessBroker& broker) { 31 * if (!broker.IsHeapObjectAlive(bar)) 32 * bar = nullptr; 33 * } 34 * 35 * void Trace(cppgc::Visitor* visitor) const { 36 * visitor->RegisterWeakCallbackMethod< 37 * GCedWithCustomWeakCallback, 38 * &GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this); 39 * } 40 * }; 41 * \endcode 42 */ 43 class V8_EXPORT LivenessBroker final { 44 public: 45 template <typename T> IsHeapObjectAlive(const T * object)46 bool IsHeapObjectAlive(const T* object) const { 47 // nullptr objects are considered alive to allow weakness to be used from 48 // stack while running into a conservative GC. Treating nullptr as dead 49 // would mean that e.g. custom collectins could not be strongified on stack. 50 return !object || 51 IsHeapObjectAliveImpl( 52 TraceTrait<T>::GetTraceDescriptor(object).base_object_payload); 53 } 54 55 template <typename T> IsHeapObjectAlive(const WeakMember<T> & weak_member)56 bool IsHeapObjectAlive(const WeakMember<T>& weak_member) const { 57 return (weak_member != kSentinelPointer) && 58 IsHeapObjectAlive<T>(weak_member.Get()); 59 } 60 61 template <typename T> IsHeapObjectAlive(const UntracedMember<T> & untraced_member)62 bool IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const { 63 return (untraced_member != kSentinelPointer) && 64 IsHeapObjectAlive<T>(untraced_member.Get()); 65 } 66 67 private: 68 LivenessBroker() = default; 69 70 bool IsHeapObjectAliveImpl(const void*) const; 71 72 friend class internal::LivenessBrokerFactory; 73 }; 74 75 } // namespace cppgc 76 77 #endif // INCLUDE_CPPGC_LIVENESS_BROKER_H_ 78