v8  10.1.124 (node 18.2.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/common.h"
13 #include "cppgc/custom-space.h"
14 #include "cppgc/heap-statistics.h"
15 #include "cppgc/visitor.h"
16 #include "v8-internal.h" // NOLINT(build/include_directory)
17 #include "v8-platform.h" // NOLINT(build/include_directory)
18 #include "v8-traced-handle.h" // NOLINT(build/include_directory)
19 
20 namespace cppgc {
21 class AllocationHandle;
22 class HeapHandle;
23 } // namespace cppgc
24 
25 namespace v8 {
26 
27 class Object;
28 
29 namespace internal {
30 class CppHeap;
31 } // namespace internal
32 
34 
35 /**
36  * Describes how V8 wrapper objects maintain references to garbage-collected C++
37  * objects.
38  */
39 struct WrapperDescriptor final {
40  /**
41  * The index used on `v8::Ojbect::SetAlignedPointerFromInternalField()` and
42  * related APIs to add additional data to an object which is used to identify
43  * JS->C++ references.
44  */
45  using InternalFieldIndex = int;
46 
47  /**
48  * Unknown embedder id. The value is reserved for internal usages and must not
49  * be used with `CppHeap`.
50  */
51  static constexpr uint16_t kUnknownEmbedderId = UINT16_MAX;
52 
53  constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index,
54  InternalFieldIndex wrappable_instance_index,
55  uint16_t embedder_id_for_garbage_collected)
56  : wrappable_type_index(wrappable_type_index),
57  wrappable_instance_index(wrappable_instance_index),
58  embedder_id_for_garbage_collected(embedder_id_for_garbage_collected) {}
59 
60  /**
61  * Index of the wrappable type.
62  */
63  InternalFieldIndex wrappable_type_index;
64 
65  /**
66  * Index of the wrappable instance.
67  */
68  InternalFieldIndex wrappable_instance_index;
69 
70  /**
71  * Embedder id identifying instances of garbage-collected objects. It is
72  * expected that the first field of the wrappable type is a uint16_t holding
73  * the id. Only references to instances of wrappables types with an id of
74  * `embedder_id_for_garbage_collected` will be considered by CppHeap.
75  */
77 };
78 
80  std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces;
81  WrapperDescriptor wrapper_descriptor;
82 };
83 
84 /**
85  * A heap for allocating managed C++ objects.
86  */
88  public:
89  static std::unique_ptr<CppHeap> Create(v8::Platform* platform,
90  const CppHeapCreateParams& params);
91 
92  virtual ~CppHeap() = default;
93 
94  /**
95  * \returns the opaque handle for allocating objects using
96  * `MakeGarbageCollected()`.
97  */
98  cppgc::AllocationHandle& GetAllocationHandle();
99 
100  /**
101  * \returns the opaque heap handle which may be used to refer to this heap in
102  * other APIs. Valid as long as the underlying `CppHeap` is alive.
103  */
104  cppgc::HeapHandle& GetHeapHandle();
105 
106  /**
107  * Terminate clears all roots and performs multiple garbage collections to
108  * reclaim potentially newly created objects in destructors.
109  *
110  * After this call, object allocation is prohibited.
111  */
112  void Terminate();
113 
114  /**
115  * \param detail_level specifies whether should return detailed
116  * statistics or only brief summary statistics.
117  * \returns current CppHeap statistics regarding memory consumption
118  * and utilization.
119  */
120  cppgc::HeapStatistics CollectStatistics(
121  cppgc::HeapStatistics::DetailLevel detail_level);
122 
123  /**
124  * Collects statistics for the given spaces and reports them to the receiver.
125  *
126  * \param custom_spaces a collection of custom space indicies.
127  * \param receiver an object that gets the results.
128  */
130  std::vector<cppgc::CustomSpaceIndex> custom_spaces,
131  std::unique_ptr<CustomSpaceStatisticsReceiver> receiver);
132 
133  /**
134  * Enables a detached mode that allows testing garbage collection using
135  * `cppgc::testing` APIs. Once used, the heap cannot be attached to an
136  * `Isolate` anymore.
137  */
139 
140  /**
141  * Performs a stop-the-world garbage collection for testing purposes.
142  *
143  * \param stack_state The stack state to assume for the garbage collection.
144  */
146 
147  /**
148  * Performs a stop-the-world minor garbage collection for testing purposes.
149  *
150  * \param stack_state The stack state to assume for the garbage collection.
151  */
153  cppgc::EmbedderStackState stack_state);
154 
155  private:
156  CppHeap() = default;
157 
158  friend class internal::CppHeap;
159 };
160 
161 class JSVisitor : public cppgc::Visitor {
162  public:
163  explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {}
164 
165  void Trace(const TracedReferenceBase& ref) {
166  if (ref.IsEmptyThreadSafe()) return;
167  Visit(ref);
168  }
169 
170  protected:
171  using cppgc::Visitor::Visit;
172 
173  virtual void Visit(const TracedReferenceBase& ref) {}
174 };
175 
176 /**
177  * Provided as input to `CppHeap::CollectCustomSpaceStatisticsAtLastGC()`.
178  *
179  * Its method is invoked with the results of the statistic collection.
180  */
182  public:
183  virtual ~CustomSpaceStatisticsReceiver() = default;
184  /**
185  * Reports the size of a space at the last GC. It is called for each space
186  * that was requested in `CollectCustomSpaceStatisticsAtLastGC()`.
187  *
188  * \param space_index The index of the space.
189  * \param bytes The total size of live objects in the space at the last GC.
190  * It is zero if there was no GC yet.
191  */
192  virtual void AllocatedBytes(cppgc::CustomSpaceIndex space_index,
193  size_t bytes) = 0;
194 };
195 
196 } // namespace v8
197 
198 namespace cppgc {
199 
200 template <typename T>
202  static cppgc::TraceDescriptor GetTraceDescriptor(const void* self) {
203  return {nullptr, Trace};
204  }
205 
206  static void Trace(Visitor* visitor, const void* self) {
207  static_cast<v8::JSVisitor*>(visitor)->Trace(
208  *static_cast<const v8::TracedReference<T>*>(self));
209  }
210 };
211 
212 } // namespace cppgc
213 
214 #endif // INCLUDE_V8_CPPGC_H_