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 
14 namespace cppgc {
15 
16 namespace internal {
17 class 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  */
44 class V8_EXPORT LivenessBroker final {
45  public:
46   template <typename T>
IsHeapObjectAlive(const T* object) const47   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>
IsHeapObjectAlive(const WeakMember<T>& weak_member) const59   bool IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
60     return IsHeapObjectAlive<T>(weak_member.Get());
61   }
62 
63   template <typename T>
IsHeapObjectAlive(const UntracedMember<T>& untraced_member) const64   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