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