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