v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
heap-consistency.h
Go to the documentation of this file.
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_CONSISTENCY_H_
6 #define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_
7 
8 #include <cstddef>
9 
10 #include "cppgc/internal/write-barrier.h"
11 #include "cppgc/macros.h"
12 #include "cppgc/trace-trait.h"
13 #include "v8config.h" // NOLINT(build/include_directory)
14 
15 namespace cppgc {
16 
17 class HeapHandle;
18 
19 namespace subtle {
20 
21 /**
22  * **DO NOT USE: Use the appropriate managed types.**
23  *
24  * Consistency helpers that aid in maintaining a consistent internal state of
25  * the garbage collector.
26  */
27 class HeapConsistency final {
28  public:
29  using WriteBarrierParams = internal::WriteBarrier::Params;
30  using WriteBarrierType = internal::WriteBarrier::Type;
31 
32  /**
33  * Gets the required write barrier type for a specific write.
34  *
35  * \param slot Slot containing the pointer to the object. The slot itself
36  * must reside in an object that has been allocated using
37  * `MakeGarbageCollected()`.
38  * \param value The pointer to the object. May be an interior pointer to an
39  * interface of the actual object.
40  * \param params Parameters that may be used for actual write barrier calls.
41  * Only filled if return value indicates that a write barrier is needed. The
42  * contents of the `params` are an implementation detail.
43  * \returns whether a write barrier is needed and which barrier to invoke.
44  */
45  static V8_INLINE WriteBarrierType GetWriteBarrierType(
46  const void* slot, const void* value, WriteBarrierParams& params) {
47  return internal::WriteBarrier::GetWriteBarrierType(slot, value, params);
48  }
49 
50  /**
51  * Gets the required write barrier type for a specific write.
52  *
53  * \param slot Slot to some part of an object. The object must not necessarily
54  have been allocated using `MakeGarbageCollected()` but can also live
55  off-heap or on stack.
56  * \param params Parameters that may be used for actual write barrier calls.
57  * Only filled if return value indicates that a write barrier is needed. The
58  * contents of the `params` are an implementation detail.
59  * \param callback Callback returning the corresponding heap handle. The
60  * callback is only invoked if the heap cannot otherwise be figured out. The
61  * callback must not allocate.
62  * \returns whether a write barrier is needed and which barrier to invoke.
63  */
64  template <typename HeapHandleCallback>
65  static V8_INLINE WriteBarrierType
66  GetWriteBarrierType(const void* slot, WriteBarrierParams& params,
67  HeapHandleCallback callback) {
68  return internal::WriteBarrier::GetWriteBarrierType(slot, params, callback);
69  }
70 
71  /**
72  * Gets the required write barrier type for a specific write.
73  * This version is meant to be used in conjunction with with a marking write
74  * barrier barrier which doesn't consider the slot.
75  *
76  * \param value The pointer to the object. May be an interior pointer to an
77  * interface of the actual object.
78  * \param params Parameters that may be used for actual write barrier calls.
79  * Only filled if return value indicates that a write barrier is needed. The
80  * contents of the `params` are an implementation detail.
81  * \returns whether a write barrier is needed and which barrier to invoke.
82  */
83  static V8_INLINE WriteBarrierType
84  GetWriteBarrierType(const void* value, WriteBarrierParams& params) {
85  return internal::WriteBarrier::GetWriteBarrierType(value, params);
86  }
87 
88  /**
89  * Conservative Dijkstra-style write barrier that processes an object if it
90  * has not yet been processed.
91  *
92  * \param params The parameters retrieved from `GetWriteBarrierType()`.
93  * \param object The pointer to the object. May be an interior pointer to a
94  * an interface of the actual object.
95  */
96  static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params,
97  const void* object) {
98  internal::WriteBarrier::DijkstraMarkingBarrier(params, object);
99  }
100 
101  /**
102  * Conservative Dijkstra-style write barrier that processes a range of
103  * elements if they have not yet been processed.
104  *
105  * \param params The parameters retrieved from `GetWriteBarrierType()`.
106  * \param first_element Pointer to the first element that should be processed.
107  * The slot itself must reside in an object that has been allocated using
108  * `MakeGarbageCollected()`.
109  * \param element_size Size of the element in bytes.
110  * \param number_of_elements Number of elements that should be processed,
111  * starting with `first_element`.
112  * \param trace_callback The trace callback that should be invoked for each
113  * element if necessary.
114  */
116  const WriteBarrierParams& params, const void* first_element,
117  size_t element_size, size_t number_of_elements,
118  TraceCallback trace_callback) {
120  params, first_element, element_size, number_of_elements,
121  trace_callback);
122  }
123 
124  /**
125  * Steele-style write barrier that re-processes an object if it has already
126  * been processed.
127  *
128  * \param params The parameters retrieved from `GetWriteBarrierType()`.
129  * \param object The pointer to the object which must point to an object that
130  * has been allocated using `MakeGarbageCollected()`. Interior pointers are
131  * not supported.
132  */
133  static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params,
134  const void* object) {
135  internal::WriteBarrier::SteeleMarkingBarrier(params, object);
136  }
137 
138  /**
139  * Generational barrier for maintaining consistency when running with multiple
140  * generations.
141  *
142  * \param params The parameters retrieved from `GetWriteBarrierType()`.
143  * \param slot Slot containing the pointer to the object. The slot itself
144  * must reside in an object that has been allocated using
145  * `MakeGarbageCollected()`.
146  */
147  static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params,
148  const void* slot) {
149  internal::WriteBarrier::GenerationalBarrier(params, slot);
150  }
151 
152  /**
153  * Generational barrier for source object that may contain outgoing pointers
154  * to objects in young generation.
155  *
156  * \param params The parameters retrieved from `GetWriteBarrierType()`.
157  * \param inner_pointer Pointer to the source object.
158  */
160  const WriteBarrierParams& params, const void* inner_pointer) {
162  inner_pointer);
163  }
164 
165  private:
166  HeapConsistency() = delete;
167 };
168 
169 /**
170  * Disallows garbage collection finalizations. Any garbage collection triggers
171  * result in a crash when in this scope.
172  *
173  * Note that the garbage collector already covers paths that can lead to garbage
174  * collections, so user code does not require checking
175  * `IsGarbageCollectionAllowed()` before allocations.
176  */
177 class V8_EXPORT V8_NODISCARD DisallowGarbageCollectionScope final {
179 
180  public:
181  /**
182  * \returns whether garbage collections are currently allowed.
183  */
184  static bool IsGarbageCollectionAllowed(HeapHandle& heap_handle);
185 
186  /**
187  * Enters a disallow garbage collection scope. Must be paired with `Leave()`.
188  * Prefer a scope instance of `DisallowGarbageCollectionScope`.
189  *
190  * \param heap_handle The corresponding heap.
191  */
192  static void Enter(HeapHandle& heap_handle);
193 
194  /**
195  * Leaves a disallow garbage collection scope. Must be paired with `Enter()`.
196  * Prefer a scope instance of `DisallowGarbageCollectionScope`.
197  *
198  * \param heap_handle The corresponding heap.
199  */
200  static void Leave(HeapHandle& heap_handle);
201 
202  /**
203  * Constructs a scoped object that automatically enters and leaves a disallow
204  * garbage collection scope based on its lifetime.
205  *
206  * \param heap_handle The corresponding heap.
207  */
208  explicit DisallowGarbageCollectionScope(HeapHandle& heap_handle);
210 
211  DisallowGarbageCollectionScope(const DisallowGarbageCollectionScope&) =
212  delete;
213  DisallowGarbageCollectionScope& operator=(
214  const DisallowGarbageCollectionScope&) = delete;
215 
216  private:
217  HeapHandle& heap_handle_;
218 };
219 
220 /**
221  * Avoids invoking garbage collection finalizations. Already running garbage
222  * collection phase are unaffected by this scope.
223  *
224  * Should only be used temporarily as the scope has an impact on memory usage
225  * and follow up garbage collections.
226  */
227 class V8_EXPORT V8_NODISCARD NoGarbageCollectionScope final {
229 
230  public:
231  /**
232  * Enters a no garbage collection scope. Must be paired with `Leave()`. Prefer
233  * a scope instance of `NoGarbageCollectionScope`.
234  *
235  * \param heap_handle The corresponding heap.
236  */
237  static void Enter(HeapHandle& heap_handle);
238 
239  /**
240  * Leaves a no garbage collection scope. Must be paired with `Enter()`. Prefer
241  * a scope instance of `NoGarbageCollectionScope`.
242  *
243  * \param heap_handle The corresponding heap.
244  */
245  static void Leave(HeapHandle& heap_handle);
246 
247  /**
248  * Constructs a scoped object that automatically enters and leaves a no
249  * garbage collection scope based on its lifetime.
250  *
251  * \param heap_handle The corresponding heap.
252  */
253  explicit NoGarbageCollectionScope(HeapHandle& heap_handle);
255 
256  NoGarbageCollectionScope(const NoGarbageCollectionScope&) = delete;
257  NoGarbageCollectionScope& operator=(const NoGarbageCollectionScope&) = delete;
258 
259  private:
260  HeapHandle& heap_handle_;
261 };
262 
263 } // namespace subtle
264 } // namespace cppgc
265 
266 #endif // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_