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_HEAP_H_
6#define INCLUDE_CPPGC_HEAP_H_
7
8#include <cstddef>
9#include <cstdint>
10#include <memory>
11#include <vector>
12
13#include "cppgc/common.h"
14#include "cppgc/custom-space.h"
15#include "cppgc/platform.h"
16#include "v8config.h"  // NOLINT(build/include_directory)
17
18/**
19 * cppgc - A C++ garbage collection library.
20 */
21namespace cppgc {
22
23class AllocationHandle;
24class HeapHandle;
25
26/**
27 * Implementation details of cppgc. Those details are considered internal and
28 * may change at any point in time without notice. Users should never rely on
29 * the contents of this namespace.
30 */
31namespace internal {
32class Heap;
33}  // namespace internal
34
35class V8_EXPORT Heap {
36 public:
37  /**
38   * Specifies the stack state the embedder is in.
39   */
40  using StackState = EmbedderStackState;
41
42  /**
43   * Specifies whether conservative stack scanning is supported.
44   */
45  enum class StackSupport : uint8_t {
46    /**
47     * Conservative stack scan is supported.
48     */
49    kSupportsConservativeStackScan,
50    /**
51     * Conservative stack scan is not supported. Embedders may use this option
52     * when using custom infrastructure that is unsupported by the library.
53     */
54    kNoConservativeStackScan,
55  };
56
57  /**
58   * Specifies supported marking types.
59   */
60  enum class MarkingType : uint8_t {
61    /**
62     * Atomic stop-the-world marking. This option does not require any write
63     * barriers but is the most intrusive in terms of jank.
64     */
65    kAtomic,
66    /**
67     * Incremental marking interleaves marking with the rest of the application
68     * workload on the same thread.
69     */
70    kIncremental,
71    /**
72     * Incremental and concurrent marking.
73     */
74    kIncrementalAndConcurrent
75  };
76
77  /**
78   * Specifies supported sweeping types.
79   */
80  enum class SweepingType : uint8_t {
81    /**
82     * Atomic stop-the-world sweeping. All of sweeping is performed at once.
83     */
84    kAtomic,
85    /**
86     * Incremental sweeping interleaves sweeping with the rest of the
87     * application workload on the same thread.
88     */
89    kIncremental,
90    /**
91     * Incremental and concurrent sweeping. Sweeping is split and interleaved
92     * with the rest of the application.
93     */
94    kIncrementalAndConcurrent
95  };
96
97  /**
98   * Constraints for a Heap setup.
99   */
100  struct ResourceConstraints {
101    /**
102     * Allows the heap to grow to some initial size in bytes before triggering
103     * garbage collections. This is useful when it is known that applications
104     * need a certain minimum heap to run to avoid repeatedly invoking the
105     * garbage collector when growing the heap.
106     */
107    size_t initial_heap_size_bytes = 0;
108  };
109
110  /**
111   * Options specifying Heap properties (e.g. custom spaces) when initializing a
112   * heap through `Heap::Create()`.
113   */
114  struct HeapOptions {
115    /**
116     * Creates reasonable defaults for instantiating a Heap.
117     *
118     * \returns the HeapOptions that can be passed to `Heap::Create()`.
119     */
120    static HeapOptions Default() { return {}; }
121
122    /**
123     * Custom spaces added to heap are required to have indices forming a
124     * numbered sequence starting at 0, i.e., their `kSpaceIndex` must
125     * correspond to the index they reside in the vector.
126     */
127    std::vector<std::unique_ptr<CustomSpaceBase>> custom_spaces;
128
129    /**
130     * Specifies whether conservative stack scan is supported. When conservative
131     * stack scan is not supported, the collector may try to invoke
132     * garbage collections using non-nestable task, which are guaranteed to have
133     * no interesting stack, through the provided Platform. If such tasks are
134     * not supported by the Platform, the embedder must take care of invoking
135     * the GC through `ForceGarbageCollectionSlow()`.
136     */
137    StackSupport stack_support = StackSupport::kSupportsConservativeStackScan;
138
139    /**
140     * Specifies which types of marking are supported by the heap.
141     */
142    MarkingType marking_support = MarkingType::kIncrementalAndConcurrent;
143
144    /**
145     * Specifies which types of sweeping are supported by the heap.
146     */
147    SweepingType sweeping_support = SweepingType::kIncrementalAndConcurrent;
148
149    /**
150     * Resource constraints specifying various properties that the internal
151     * GC scheduler follows.
152     */
153    ResourceConstraints resource_constraints;
154  };
155
156  /**
157   * Creates a new heap that can be used for object allocation.
158   *
159   * \param platform implemented and provided by the embedder.
160   * \param options HeapOptions specifying various properties for the Heap.
161   * \returns a new Heap instance.
162   */
163  static std::unique_ptr<Heap> Create(
164      std::shared_ptr<Platform> platform,
165      HeapOptions options = HeapOptions::Default());
166
167  virtual ~Heap() = default;
168
169  /**
170   * Forces garbage collection.
171   *
172   * \param source String specifying the source (or caller) triggering a
173   *   forced garbage collection.
174   * \param reason String specifying the reason for the forced garbage
175   *   collection.
176   * \param stack_state The embedder stack state, see StackState.
177   */
178  void ForceGarbageCollectionSlow(
179      const char* source, const char* reason,
180      StackState stack_state = StackState::kMayContainHeapPointers);
181
182  /**
183   * \returns the opaque handle for allocating objects using
184   * `MakeGarbageCollected()`.
185   */
186  AllocationHandle& GetAllocationHandle();
187
188  /**
189   * \returns the opaque heap handle which may be used to refer to this heap in
190   *   other APIs. Valid as long as the underlying `Heap` is alive.
191   */
192  HeapHandle& GetHeapHandle();
193
194 private:
195  Heap() = default;
196
197  friend class internal::Heap;
198};
199
200}  // namespace cppgc
201
202#endif  // INCLUDE_CPPGC_HEAP_H_
203