v8-cppgc.h 6.2 KB

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