v8  9.0.257(node16.0.0)
V8 is Google's open source JavaScript engine
v8-cppgc.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_V8_CPPGC_H_
6 #define INCLUDE_V8_CPPGC_H_
7 
8 #include <cstdint>
9 #include <memory>
10 #include <vector>
11 
12 #include "cppgc/custom-space.h"
13 #include "cppgc/heap-statistics.h"
14 #include "cppgc/internal/write-barrier.h"
15 #include "cppgc/visitor.h"
16 #include "v8-internal.h" // NOLINT(build/include_directory)
17 #include "v8.h" // NOLINT(build/include_directory)
18 
19 namespace cppgc {
20 class AllocationHandle;
21 class HeapHandle;
22 } // namespace cppgc
23 
24 namespace v8 {
25 
26 namespace internal {
27 class CppHeap;
28 } // namespace internal
29 
30 /**
31  * Describes how V8 wrapper objects maintain references to garbage-collected C++
32  * objects.
33  */
34 struct WrapperDescriptor final {
35  /**
36  * The index used on `v8::Ojbect::SetAlignedPointerFromInternalField()` and
37  * related APIs to add additional data to an object which is used to identify
38  * JS->C++ references.
39  */
40  using InternalFieldIndex = int;
41 
42  /**
43  * Unknown embedder id. The value is reserved for internal usages and must not
44  * be used with `CppHeap`.
45  */
46  static constexpr uint16_t kUnknownEmbedderId = UINT16_MAX;
47 
48  constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index,
49  InternalFieldIndex wrappable_instance_index,
50  uint16_t embedder_id_for_garbage_collected)
51  : wrappable_type_index(wrappable_type_index),
52  wrappable_instance_index(wrappable_instance_index),
53  embedder_id_for_garbage_collected(embedder_id_for_garbage_collected) {}
54 
55  /**
56  * Index of the wrappable type.
57  */
58  InternalFieldIndex wrappable_type_index;
59 
60  /**
61  * Index of the wrappable instance.
62  */
63  InternalFieldIndex wrappable_instance_index;
64 
65  /**
66  * Embedder id identifying instances of garbage-collected objects. It is
67  * expected that the first field of the wrappable type is a uint16_t holding
68  * the id. Only references to instances of wrappables types with an id of
69  * `embedder_id_for_garbage_collected` will be considered by CppHeap.
70  */
72 };
73 
77 
78  std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces;
79  WrapperDescriptor wrapper_descriptor;
80 };
81 
82 /**
83  * A heap for allocating managed C++ objects.
84  */
86  public:
87  static std::unique_ptr<CppHeap> Create(v8::Platform* platform,
88  const CppHeapCreateParams& params);
89 
90  virtual ~CppHeap() = default;
91 
92  /**
93  * \returns the opaque handle for allocating objects using
94  * `MakeGarbageCollected()`.
95  */
96  cppgc::AllocationHandle& GetAllocationHandle();
97 
98  /**
99  * \returns the opaque heap handle which may be used to refer to this heap in
100  * other APIs. Valid as long as the underlying `CppHeap` is alive.
101  */
102  cppgc::HeapHandle& GetHeapHandle();
103 
104  /**
105  * Terminate clears all roots and performs multiple garbage collections to
106  * reclaim potentially newly created objects in destructors.
107  *
108  * After this call, object allocation is prohibited.
109  */
110  void Terminate();
111 
112  /**
113  * \param detail_level specifies whether should return detailed
114  * statistics or only brief summary statistics.
115  * \returns current CppHeap statistics regarding memory consumption
116  * and utilization.
117  */
118  cppgc::HeapStatistics CollectStatistics(
119  cppgc::HeapStatistics::DetailLevel detail_level);
120 
121  private:
122  CppHeap() = default;
123 
124  friend class internal::CppHeap;
125 };
126 
127 class JSVisitor : public cppgc::Visitor {
128  public:
129  explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {}
130 
131  void Trace(const TracedReferenceBase& ref) {
132  if (ref.IsEmptyThreadSafe()) return;
133  Visit(ref);
134  }
135 
136  protected:
137  using cppgc::Visitor::Visit;
138 
139  virtual void Visit(const TracedReferenceBase& ref) {}
140 };
141 
142 /**
143  * **DO NOT USE: Use the appropriate managed types.**
144  *
145  * Consistency helpers that aid in maintaining a consistent internal state of
146  * the garbage collector.
147  */
148 class V8_EXPORT JSHeapConsistency final {
149  public:
150  using WriteBarrierParams = cppgc::internal::WriteBarrier::Params;
151  using WriteBarrierType = cppgc::internal::WriteBarrier::Type;
152 
153  /**
154  * Gets the required write barrier type for a specific write.
155  *
156  * Note: Handling for C++ to JS references.
157  *
158  * \param ref The reference being written to.
159  * \param params Parameters that may be used for actual write barrier calls.
160  * Only filled if return value indicates that a write barrier is needed. The
161  * contents of the `params` are an implementation detail.
162  * \param callback Callback returning the corresponding heap handle. The
163  * callback is only invoked if the heap cannot otherwise be figured out. The
164  * callback must not allocate.
165  * \returns whether a write barrier is needed and which barrier to invoke.
166  */
167  template <typename HeapHandleCallback>
168  static V8_INLINE WriteBarrierType
170  WriteBarrierParams& params, HeapHandleCallback callback) {
171  if (ref.IsEmpty()) return WriteBarrierType::kNone;
172 
173  if (V8_LIKELY(!cppgc::internal::WriteBarrier::
175  return cppgc::internal::WriteBarrier::Type::kNone;
176  }
177  cppgc::HeapHandle& handle = callback();
178  if (!cppgc::subtle::HeapState::IsMarking(handle)) {
179  return cppgc::internal::WriteBarrier::Type::kNone;
180  }
181  params.heap = &handle;
182 #if V8_ENABLE_CHECKS
183  params.type = cppgc::internal::WriteBarrier::Type::kMarking;
184 #endif // !V8_ENABLE_CHECKS
185  return cppgc::internal::WriteBarrier::Type::kMarking;
186  }
187 
188  /**
189  * Gets the required write barrier type for a specific write.
190  *
191  * Note: Handling for JS to C++ references.
192  *
193  * \param wrapper The wrapper that has been written into.
194  * \param wrapper_index The wrapper index in `wrapper` that has been written
195  * into.
196  * \param wrappable The value that was written.
197  * \param params Parameters that may be used for actual write barrier calls.
198  * Only filled if return value indicates that a write barrier is needed. The
199  * contents of the `params` are an implementation detail.
200  * \param callback Callback returning the corresponding heap handle. The
201  * callback is only invoked if the heap cannot otherwise be figured out. The
202  * callback must not allocate.
203  * \returns whether a write barrier is needed and which barrier to invoke.
204  */
205  template <typename HeapHandleCallback>
206  static V8_INLINE WriteBarrierType GetWriteBarrierType(
207  v8::Local<v8::Object>& wrapper, int wrapper_index, const void* wrappable,
208  WriteBarrierParams& params, HeapHandleCallback callback) {
209 #if V8_ENABLE_CHECKS
210  CheckWrapper(wrapper, wrapper_index, wrappable);
211 #endif // V8_ENABLE_CHECKS
212  return cppgc::internal::WriteBarrier::
213  GetWriteBarrierTypeForExternallyReferencedObject(wrappable, params,
214  callback);
215  }
216 
217  /**
218  * Conservative Dijkstra-style write barrier that processes an object if it
219  * has not yet been processed.
220  *
221  * \param params The parameters retrieved from `GetWriteBarrierType()`.
222  * \param ref The reference being written to.
223  */
224  static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params,
225  cppgc::HeapHandle& heap_handle,
226  const TracedReferenceBase& ref) {
227  cppgc::internal::WriteBarrier::CheckParams(WriteBarrierType::kMarking,
228  params);
229  DijkstraMarkingBarrierSlow(heap_handle, ref);
230  }
231 
232  /**
233  * Conservative Dijkstra-style write barrier that processes an object if it
234  * has not yet been processed.
235  *
236  * \param params The parameters retrieved from `GetWriteBarrierType()`.
237  * \param object The pointer to the object. May be an interior pointer to a
238  * an interface of the actual object.
239  */
240  static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params,
241  cppgc::HeapHandle& heap_handle,
242  const void* object) {
243  cppgc::internal::WriteBarrier::DijkstraMarkingBarrier(params, object);
244  }
245 
246  /**
247  * Generational barrier for maintaining consistency when running with multiple
248  * generations.
249  *
250  * \param params The parameters retrieved from `GetWriteBarrierType()`.
251  * \param ref The reference being written to.
252  */
253  static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params,
254  const TracedReferenceBase& ref) {}
255 
256  private:
257  JSHeapConsistency() = delete;
258 
259  static void CheckWrapper(v8::Local<v8::Object>&, int, const void*);
260 
261  static void DijkstraMarkingBarrierSlow(cppgc::HeapHandle&,
262  const TracedReferenceBase& ref);
263 };
264 
265 } // namespace v8
266 
267 namespace cppgc {
268 
269 template <typename T>
271  static void Trace(Visitor* visitor, const v8::TracedReference<T>* self) {
272  static_cast<v8::JSVisitor*>(visitor)->Trace(*self);
273  }
274 };
275 
276 } // namespace cppgc
277 
278 #endif // INCLUDE_V8_CPPGC_H_
v8::WrapperDescriptor::kUnknownEmbedderId
static constexpr uint16_t kUnknownEmbedderId
Definition: v8-cppgc.h:46
v8::WrapperDescriptor::embedder_id_for_garbage_collected
uint16_t embedder_id_for_garbage_collected
Definition: v8-cppgc.h:71
v8::CppHeapCreateParams
Definition: v8-cppgc.h:74
cppgc::subtle::HeapState::IsMarking
static bool IsMarking(const HeapHandle &heap_handle)
v8::CppHeapCreateParams::operator=
CppHeapCreateParams & operator=(const CppHeapCreateParams &)=delete
v8::CppHeap::Create
static std::unique_ptr< CppHeap > Create(v8::Platform *platform, const CppHeapCreateParams &params)
v8::JSHeapConsistency::GetWriteBarrierType
static V8_INLINE WriteBarrierType GetWriteBarrierType(const TracedReferenceBase &ref, WriteBarrierParams &params, HeapHandleCallback callback)
Definition: v8-cppgc.h:169
v8::CppHeap::GetHeapHandle
cppgc::HeapHandle & GetHeapHandle()
v8::CppHeapCreateParams::custom_spaces
std::vector< std::unique_ptr< cppgc::CustomSpaceBase > > custom_spaces
Definition: v8-cppgc.h:78
v8::WrapperDescriptor::wrappable_type_index
InternalFieldIndex wrappable_type_index
Definition: v8-cppgc.h:58
v8::CppHeapCreateParams::wrapper_descriptor
WrapperDescriptor wrapper_descriptor
Definition: v8-cppgc.h:79
V8_INLINE
#define V8_INLINE
Definition: v8config.h:380
cppgc::subtle
Definition: cross-thread-persistent.h:310
cppgc::internal::WriteBarrier::Type::kMarking
@ kMarking
cppgc::Visitor::Visitor
Visitor(Key)
Definition: visitor.h:60
v8::Object
Definition: v8.h:3914
cppgc::internal::WriteBarrier::IsAnyIncrementalOrConcurrentMarking
static bool IsAnyIncrementalOrConcurrentMarking()
Definition: write-barrier.h:92
v8::JSVisitor
Definition: v8-cppgc.h:127
v8::JSVisitor::JSVisitor
JSVisitor(cppgc::Visitor::Key key)
Definition: v8-cppgc.h:129
cppgc::internal::WriteBarrier::Type::kNone
@ kNone
v8::JSHeapConsistency::DijkstraMarkingBarrier
static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams &params, cppgc::HeapHandle &heap_handle, const void *object)
Definition: v8-cppgc.h:240
cppgc
Definition: allocation.h:17
v8::CppHeap::CollectStatistics
cppgc::HeapStatistics CollectStatistics(cppgc::HeapStatistics::DetailLevel detail_level)
v8::CppHeap::GetAllocationHandle
cppgc::AllocationHandle & GetAllocationHandle()
v8::JSHeapConsistency::GetWriteBarrierType
static V8_INLINE WriteBarrierType GetWriteBarrierType(v8::Local< v8::Object > &wrapper, int wrapper_index, const void *wrappable, WriteBarrierParams &params, HeapHandleCallback callback)
Definition: v8-cppgc.h:206
v8::WrapperDescriptor::wrappable_instance_index
InternalFieldIndex wrappable_instance_index
Definition: v8-cppgc.h:63
V8_EXPORT
#define V8_EXPORT
Definition: v8config.h:512
cppgc::Visitor::Key
Definition: visitor.h:54
v8::CppHeap::Terminate
void Terminate()
v8::TracedReferenceBase::IsEmptyThreadSafe
bool IsEmptyThreadSafe() const
Definition: v8.h:856
v8::internal
Definition: v8-cppgc.h:26
V8_LIKELY
#define V8_LIKELY(condition)
Definition: v8config.h:444
v8
Definition: libplatform.h:15
cppgc::Visitor
Definition: visitor.h:52
v8::JSVisitor::Visit
virtual void Visit(const TracedReferenceBase &ref)
Definition: v8-cppgc.h:139
v8::JSVisitor::Trace
void Trace(const TracedReferenceBase &ref)
Definition: v8-cppgc.h:131
v8::JSHeapConsistency::DijkstraMarkingBarrier
static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams &params, cppgc::HeapHandle &heap_handle, const TracedReferenceBase &ref)
Definition: v8-cppgc.h:224
v8::Platform
Definition: v8-platform.h:522
cppgc::internal::WriteBarrier::Params
Definition: write-barrier.h:36
v8::WrapperDescriptor::WrapperDescriptor
constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index, InternalFieldIndex wrappable_instance_index, uint16_t embedder_id_for_garbage_collected)
Definition: v8-cppgc.h:48
cppgc::internal::WriteBarrier::Type
Type
Definition: write-barrier.h:30
v8::CppHeapCreateParams::CppHeapCreateParams
CppHeapCreateParams(const CppHeapCreateParams &)=delete
v8::TracedReferenceBase
Definition: v8.h:833
cppgc::internal::WriteBarrier::DijkstraMarkingBarrier
static V8_INLINE void DijkstraMarkingBarrier(const Params &params, const void *object)
Definition: write-barrier.h:337
v8::CppHeap
Definition: v8-cppgc.h:85
v8::V8::Local
friend class Local
Definition: v8.h:10134
v8::CppHeap::~CppHeap
virtual ~CppHeap()=default
cppgc::TraceTrait< v8::TracedReference< T > >::Trace
static void Trace(Visitor *visitor, const v8::TracedReference< T > *self)
Definition: v8-cppgc.h:271
cppgc::HeapStatistics::DetailLevel
DetailLevel
Definition: heap-statistics.h:27
cppgc::internal
Definition: allocation.h:22
cppgc::CustomSpaceBase
Definition: custom-space.h:24
v8::TracedReferenceBase::IsEmpty
bool IsEmpty() const
Definition: v8.h:839
cppgc::internal::BasicMember::TraceTrait
friend struct cppgc::TraceTrait
Definition: member.h:208
v8::V8::TracedReference
friend class TracedReference
Definition: v8.h:10143
v8::JSHeapConsistency::GenerationalBarrier
static V8_INLINE void GenerationalBarrier(const WriteBarrierParams &params, const TracedReferenceBase &ref)
Definition: v8-cppgc.h:253
cppgc::internal::WriteBarrier::Params::heap
HeapHandle * heap
Definition: write-barrier.h:37
cppgc::internal::WriteBarrier::CheckParams
static void CheckParams(Type expected_type, const Params &params)
Definition: write-barrier.h:86