v8  10.1.124 (node 18.2.0)
V8 is Google's open source JavaScript engine
v8-embedder-heap.h
Go to the documentation of this file.
1 // Copyright 2021 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_EMBEDDER_HEAP_H_
6 #define INCLUDE_V8_EMBEDDER_HEAP_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <utility>
12 #include <vector>
13 
14 #include "cppgc/common.h"
15 #include "v8-local-handle.h" // NOLINT(build/include_directory)
16 #include "v8-traced-handle.h" // NOLINT(build/include_directory)
17 #include "v8config.h" // NOLINT(build/include_directory)
18 
19 namespace v8 {
20 
21 class Data;
22 class Isolate;
23 class Value;
24 
25 namespace internal {
26 class LocalEmbedderHeapTracer;
27 } // namespace internal
28 
29 /**
30  * Handler for embedder roots on non-unified heap garbage collections.
31  */
33  public:
34  virtual ~EmbedderRootsHandler() = default;
35 
36  /**
37  * Returns true if the TracedGlobal handle should be considered as root for
38  * the currently running non-tracing garbage collection and false otherwise.
39  * The default implementation will keep all TracedGlobal references as roots.
40  *
41  * If this returns false, then V8 may decide that the object referred to by
42  * such a handle is reclaimed. In that case:
43  * - No action is required if handles are used with destructors, i.e., by just
44  * using |TracedGlobal|.
45  * - When run without destructors, i.e., by using |TracedReference|, V8 calls
46  * |ResetRoot|.
47  *
48  * Note that the |handle| is different from the handle that the embedder holds
49  * for retaining the object. The embedder may use |WrapperClassId()| to
50  * distinguish cases where it wants handles to be treated as roots from not
51  * being treated as roots.
52  */
53  virtual bool IsRoot(const v8::TracedReference<v8::Value>& handle) = 0;
54 
55  V8_DEPRECATED("See v8::TracedGlobal class comment.")
56  virtual bool IsRoot(const v8::TracedGlobal<v8::Value>& handle) {
57  return true;
58  }
59 
60  /**
61  * Used in combination with |IsRoot|. Called by V8 when an
62  * object that is backed by a handle is reclaimed by a non-tracing garbage
63  * collection. It is up to the embedder to reset the original handle.
64  *
65  * Note that the |handle| is different from the handle that the embedder holds
66  * for retaining the object. It is up to the embedder to find the original
67  * handle via the object or class id.
68  */
69  virtual void ResetRoot(const v8::TracedReference<v8::Value>& handle) = 0;
70 };
71 
72 /**
73  * Interface for tracing through the embedder heap. During a V8 garbage
74  * collection, V8 collects hidden fields of all potential wrappers, and at the
75  * end of its marking phase iterates the collection and asks the embedder to
76  * trace through its heap and use reporter to report each JavaScript object
77  * reachable from any of the given wrappers.
78  */
80  public:
81  using EmbedderStackState = cppgc::EmbedderStackState;
82 
84  kNoFlags = 0,
85  kReduceMemory = 1 << 0,
86  kForced = 1 << 2,
87  };
88 
89  /**
90  * Interface for iterating through TracedGlobal handles.
91  */
93  public:
94  virtual ~TracedGlobalHandleVisitor() = default;
95  V8_DEPRECATED("See v8::TracedGlobal class comment.")
96  virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& handle) {}
97  virtual void VisitTracedReference(const TracedReference<Value>& handle) {}
98  };
99 
100  /**
101  * Summary of a garbage collection cycle. See |TraceEpilogue| on how the
102  * summary is reported.
103  */
104  struct TraceSummary {
105  /**
106  * Time spent managing the retained memory in milliseconds. This can e.g.
107  * include the time tracing through objects in the embedder.
108  */
109  double time = 0.0;
110 
111  /**
112  * Memory retained by the embedder through the |EmbedderHeapTracer|
113  * mechanism in bytes.
114  */
115  size_t allocated_size = 0;
116  };
117 
118  virtual ~EmbedderHeapTracer() = default;
119 
120  /**
121  * Iterates all TracedGlobal handles created for the v8::Isolate the tracer is
122  * attached to.
123  */
125 
126  /**
127  * Called by the embedder to set the start of the stack which is e.g. used by
128  * V8 to determine whether handles are used from stack or heap.
129  */
130  void SetStackStart(void* stack_start);
131 
132  /**
133  * Called by v8 to register internal fields of found wrappers.
134  *
135  * The embedder is expected to store them somewhere and trace reachable
136  * wrappers from them when called through |AdvanceTracing|.
137  */
138  virtual void RegisterV8References(
139  const std::vector<std::pair<void*, void*>>& embedder_fields) = 0;
140 
142 
143  /**
144  * Called at the beginning of a GC cycle.
145  */
146  virtual void TracePrologue(TraceFlags flags) {}
147 
148  /**
149  * Called to advance tracing in the embedder.
150  *
151  * The embedder is expected to trace its heap starting from wrappers reported
152  * by RegisterV8References method, and report back all reachable wrappers.
153  * Furthermore, the embedder is expected to stop tracing by the given
154  * deadline. A deadline of infinity means that tracing should be finished.
155  *
156  * Returns |true| if tracing is done, and false otherwise.
157  */
158  virtual bool AdvanceTracing(double deadline_in_ms) = 0;
159 
160  /*
161  * Returns true if there no more tracing work to be done (see AdvanceTracing)
162  * and false otherwise.
163  */
164  virtual bool IsTracingDone() = 0;
165 
166  /**
167  * Called at the end of a GC cycle.
168  *
169  * Note that allocation is *not* allowed within |TraceEpilogue|. Can be
170  * overriden to fill a |TraceSummary| that is used by V8 to schedule future
171  * garbage collections.
172  */
173  virtual void TraceEpilogue(TraceSummary* trace_summary) {}
174 
175  /**
176  * Called upon entering the final marking pause. No more incremental marking
177  * steps will follow this call.
178  */
179  virtual void EnterFinalPause(EmbedderStackState stack_state) = 0;
180 
181  /*
182  * Called by the embedder to request immediate finalization of the currently
183  * running tracing phase that has been started with TracePrologue and not
184  * yet finished with TraceEpilogue.
185  *
186  * Will be a noop when currently not in tracing.
187  *
188  * This is an experimental feature.
189  */
191 
192  /**
193  * See documentation on EmbedderRootsHandler.
194  */
195  virtual bool IsRootForNonTracingGC(
196  const v8::TracedReference<v8::Value>& handle);
197  V8_DEPRECATED("See v8::TracedGlobal class comment.")
198  virtual bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle);
199 
200  /**
201  * See documentation on EmbedderRootsHandler.
202  */
204  const v8::TracedReference<v8::Value>& handle);
205 
206  /*
207  * Called by the embedder to signal newly allocated or freed memory. Not bound
208  * to tracing phases. Embedders should trade off when increments are reported
209  * as V8 may consult global heuristics on whether to trigger garbage
210  * collection on this change.
211  */
212  void IncreaseAllocatedSize(size_t bytes);
213  void DecreaseAllocatedSize(size_t bytes);
214 
215  /*
216  * Returns the v8::Isolate this tracer is attached too and |nullptr| if it
217  * is not attached to any v8::Isolate.
218  */
219  v8::Isolate* isolate() const { return isolate_; }
220 
221  protected:
222  v8::Isolate* isolate_ = nullptr;
223 
224  friend class internal::LocalEmbedderHeapTracer;
225 };
226 
227 } // namespace v8
228 
229 #endif // INCLUDE_V8_EMBEDDER_HEAP_H_