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  */
21 namespace cppgc {
22 
23 class AllocationHandle;
24 class 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  */
31 namespace internal {
32 class Heap;
33 }  // namespace internal
34 
35 class 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      */
Defaultcppgc::Heap::HeapOptions120     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