v8-embedder-heap.h 6.7 KB

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