xref: /third_party/node/deps/v8/src/heap/cppgc/heap-base.h (revision 1cb0ef41)
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 V8_HEAP_CPPGC_HEAP_BASE_H_
6#define V8_HEAP_CPPGC_HEAP_BASE_H_
7
8#include <memory>
9#include <set>
10
11#include "include/cppgc/heap-statistics.h"
12#include "include/cppgc/heap.h"
13#include "include/cppgc/internal/persistent-node.h"
14#include "include/cppgc/macros.h"
15#include "src/base/macros.h"
16#include "src/heap/cppgc/compactor.h"
17#include "src/heap/cppgc/garbage-collector.h"
18#include "src/heap/cppgc/heap-object-header.h"
19#include "src/heap/cppgc/marker.h"
20#include "src/heap/cppgc/metric-recorder.h"
21#include "src/heap/cppgc/object-allocator.h"
22#include "src/heap/cppgc/platform.h"
23#include "src/heap/cppgc/process-heap-statistics.h"
24#include "src/heap/cppgc/process-heap.h"
25#include "src/heap/cppgc/raw-heap.h"
26#include "src/heap/cppgc/sweeper.h"
27#include "v8config.h"  // NOLINT(build/include_directory)
28
29#if defined(CPPGC_CAGED_HEAP)
30#include "src/heap/cppgc/caged-heap.h"
31#endif
32
33#if defined(CPPGC_YOUNG_GENERATION)
34#include "src/heap/cppgc/remembered-set.h"
35#endif
36
37namespace v8 {
38namespace base {
39class LsanPageAllocator;
40}  // namespace base
41}  // namespace v8
42
43namespace heap {
44namespace base {
45class Stack;
46}  // namespace base
47}  // namespace heap
48
49namespace cppgc {
50namespace subtle {
51class DisallowGarbageCollectionScope;
52class NoGarbageCollectionScope;
53}  // namespace subtle
54
55namespace testing {
56class Heap;
57class OverrideEmbedderStackStateScope;
58}  // namespace testing
59
60class Platform;
61
62class V8_EXPORT HeapHandle {
63 private:
64  HeapHandle() = default;
65  friend class internal::HeapBase;
66};
67
68namespace internal {
69
70class FatalOutOfMemoryHandler;
71class PageBackend;
72class PreFinalizerHandler;
73class StatsCollector;
74
75// Base class for heap implementations.
76class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
77 public:
78  using StackSupport = cppgc::Heap::StackSupport;
79  using MarkingType = cppgc::Heap::MarkingType;
80  using SweepingType = cppgc::Heap::SweepingType;
81
82  static HeapBase& From(cppgc::HeapHandle& heap_handle) {
83    return static_cast<HeapBase&>(heap_handle);
84  }
85  static const HeapBase& From(const cppgc::HeapHandle& heap_handle) {
86    return static_cast<const HeapBase&>(heap_handle);
87  }
88
89  HeapBase(std::shared_ptr<cppgc::Platform> platform,
90           const std::vector<std::unique_ptr<CustomSpaceBase>>& custom_spaces,
91           StackSupport stack_support, MarkingType marking_support,
92           SweepingType sweeping_support);
93  virtual ~HeapBase();
94
95  HeapBase(const HeapBase&) = delete;
96  HeapBase& operator=(const HeapBase&) = delete;
97
98  RawHeap& raw_heap() { return raw_heap_; }
99  const RawHeap& raw_heap() const { return raw_heap_; }
100
101  cppgc::Platform* platform() { return platform_.get(); }
102  const cppgc::Platform* platform() const { return platform_.get(); }
103
104  FatalOutOfMemoryHandler& oom_handler() { return *oom_handler_.get(); }
105  const FatalOutOfMemoryHandler& oom_handler() const {
106    return *oom_handler_.get();
107  }
108
109  PageBackend* page_backend() { return page_backend_.get(); }
110  const PageBackend* page_backend() const { return page_backend_.get(); }
111
112  StatsCollector* stats_collector() { return stats_collector_.get(); }
113  const StatsCollector* stats_collector() const {
114    return stats_collector_.get();
115  }
116
117#if defined(CPPGC_CAGED_HEAP)
118  CagedHeap& caged_heap() { return caged_heap_; }
119  const CagedHeap& caged_heap() const { return caged_heap_; }
120#endif
121
122  heap::base::Stack* stack() { return stack_.get(); }
123
124  PreFinalizerHandler* prefinalizer_handler() {
125    return prefinalizer_handler_.get();
126  }
127  const PreFinalizerHandler* prefinalizer_handler() const {
128    return prefinalizer_handler_.get();
129  }
130
131  MarkerBase* marker() const { return marker_.get(); }
132  std::unique_ptr<MarkerBase>& GetMarkerRefForTesting() { return marker_; }
133
134  Compactor& compactor() { return compactor_; }
135
136  ObjectAllocator& object_allocator() { return object_allocator_; }
137  const ObjectAllocator& object_allocator() const { return object_allocator_; }
138
139  Sweeper& sweeper() { return sweeper_; }
140  const Sweeper& sweeper() const { return sweeper_; }
141
142  PersistentRegion& GetStrongPersistentRegion() {
143    return strong_persistent_region_;
144  }
145  const PersistentRegion& GetStrongPersistentRegion() const {
146    return strong_persistent_region_;
147  }
148  PersistentRegion& GetWeakPersistentRegion() {
149    return weak_persistent_region_;
150  }
151  const PersistentRegion& GetWeakPersistentRegion() const {
152    return weak_persistent_region_;
153  }
154  CrossThreadPersistentRegion& GetStrongCrossThreadPersistentRegion() {
155    return strong_cross_thread_persistent_region_;
156  }
157  const CrossThreadPersistentRegion& GetStrongCrossThreadPersistentRegion()
158      const {
159    return strong_cross_thread_persistent_region_;
160  }
161  CrossThreadPersistentRegion& GetWeakCrossThreadPersistentRegion() {
162    return weak_cross_thread_persistent_region_;
163  }
164  const CrossThreadPersistentRegion& GetWeakCrossThreadPersistentRegion()
165      const {
166    return weak_cross_thread_persistent_region_;
167  }
168
169#if defined(CPPGC_YOUNG_GENERATION)
170  OldToNewRememberedSet& remembered_set() { return remembered_set_; }
171#endif  // defined(CPPGC_YOUNG_GENERATION)
172
173  size_t ObjectPayloadSize() const;
174
175  StackSupport stack_support() const { return stack_support_; }
176  const EmbedderStackState* override_stack_state() const {
177    return override_stack_state_.get();
178  }
179
180  // Termination drops all roots (clears them out) and runs garbage collections
181  // in a bounded fixed point loop  until no new objects are created in
182  // destructors. Exceeding the loop bound results in a crash.
183  void Terminate();
184
185  bool in_disallow_gc_scope() const { return disallow_gc_scope_ > 0; }
186  bool in_atomic_pause() const { return in_atomic_pause_; }
187
188  HeapStatistics CollectStatistics(HeapStatistics::DetailLevel);
189
190  EmbedderStackState stack_state_of_prev_gc() const {
191    return stack_state_of_prev_gc_;
192  }
193  void SetStackStateOfPrevGC(EmbedderStackState stack_state) {
194    stack_state_of_prev_gc_ = stack_state;
195  }
196
197  uintptr_t stack_end_of_current_gc() const { return stack_end_of_current_gc_; }
198  void SetStackEndOfCurrentGC(uintptr_t stack_end) {
199    stack_end_of_current_gc_ = stack_end;
200  }
201
202  void SetInAtomicPauseForTesting(bool value) { in_atomic_pause_ = value; }
203
204  virtual void StartIncrementalGarbageCollectionForTesting() = 0;
205  virtual void FinalizeIncrementalGarbageCollectionForTesting(
206      EmbedderStackState) = 0;
207
208  void SetMetricRecorder(std::unique_ptr<MetricRecorder> histogram_recorder) {
209    stats_collector_->SetMetricRecorder(std::move(histogram_recorder));
210  }
211
212  int GetCreationThreadId() const { return creation_thread_id_; }
213
214  MarkingType marking_support() const { return marking_support_; }
215  SweepingType sweeping_support() const { return sweeping_support_; }
216
217 protected:
218  // Used by the incremental scheduler to finalize a GC if supported.
219  virtual void FinalizeIncrementalGarbageCollectionIfNeeded(
220      cppgc::Heap::StackState) = 0;
221
222  bool in_no_gc_scope() const { return no_gc_scope_ > 0; }
223
224  bool IsMarking() const { return marker_.get(); }
225
226  // Returns amount of bytes allocated while executing prefinalizers.
227  size_t ExecutePreFinalizers();
228
229#if defined(CPPGC_YOUNG_GENERATION)
230  void ResetRememberedSet();
231#endif  // defined(CPPGC_YOUNG_GENERATION)
232
233  PageAllocator* page_allocator() const;
234
235  RawHeap raw_heap_;
236  std::shared_ptr<cppgc::Platform> platform_;
237  std::unique_ptr<FatalOutOfMemoryHandler> oom_handler_;
238
239#if defined(LEAK_SANITIZER)
240  std::unique_ptr<v8::base::LsanPageAllocator> lsan_page_allocator_;
241#endif  // LEAK_SANITIZER
242
243#if defined(CPPGC_CAGED_HEAP)
244  CagedHeap caged_heap_;
245#endif  // CPPGC_CAGED_HEAP
246  std::unique_ptr<PageBackend> page_backend_;
247
248  // HeapRegistry requires access to page_backend_.
249  HeapRegistry::Subscription heap_registry_subscription_{*this};
250
251  std::unique_ptr<StatsCollector> stats_collector_;
252  std::unique_ptr<heap::base::Stack> stack_;
253  std::unique_ptr<PreFinalizerHandler> prefinalizer_handler_;
254  std::unique_ptr<MarkerBase> marker_;
255
256  Compactor compactor_;
257  ObjectAllocator object_allocator_;
258  Sweeper sweeper_;
259
260  PersistentRegion strong_persistent_region_;
261  PersistentRegion weak_persistent_region_;
262  CrossThreadPersistentRegion strong_cross_thread_persistent_region_;
263  CrossThreadPersistentRegion weak_cross_thread_persistent_region_;
264
265  ProcessHeapStatisticsUpdater::AllocationObserverImpl
266      allocation_observer_for_PROCESS_HEAP_STATISTICS_;
267#if defined(CPPGC_YOUNG_GENERATION)
268  OldToNewRememberedSet remembered_set_;
269#endif  // defined(CPPGC_YOUNG_GENERATION)
270
271  size_t no_gc_scope_ = 0;
272  size_t disallow_gc_scope_ = 0;
273
274  const StackSupport stack_support_;
275  EmbedderStackState stack_state_of_prev_gc_ =
276      EmbedderStackState::kNoHeapPointers;
277  std::unique_ptr<EmbedderStackState> override_stack_state_;
278
279  // Marker that signals end of the interesting stack region in which on-heap
280  // pointers can be found.
281  uintptr_t stack_end_of_current_gc_ = 0;
282
283  bool in_atomic_pause_ = false;
284
285  int creation_thread_id_ = v8::base::OS::GetCurrentThreadId();
286
287  const MarkingType marking_support_;
288  const SweepingType sweeping_support_;
289
290  friend class MarkerBase::IncrementalMarkingTask;
291  friend class cppgc::subtle::DisallowGarbageCollectionScope;
292  friend class cppgc::subtle::NoGarbageCollectionScope;
293  friend class cppgc::testing::Heap;
294  friend class cppgc::testing::OverrideEmbedderStackStateScope;
295};
296
297}  // namespace internal
298}  // namespace cppgc
299
300#endif  // V8_HEAP_CPPGC_HEAP_BASE_H_
301