v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
cpp-heap.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 V8_HEAP_CPPGC_JS_CPP_HEAP_H_
6#define V8_HEAP_CPPGC_JS_CPP_HEAP_H_
7
8#if CPPGC_IS_STANDALONE
9static_assert(
10 false, "V8 targets can not be built with cppgc_is_standalone set to true.");
11#endif
12
13#include <optional>
14
16#include "include/v8-cppgc.h"
17#include "include/v8-metrics.h"
18#include "src/base/flags.h"
19#include "src/base/macros.h"
25#include "src/logging/metrics.h"
27
28namespace v8 {
29
30class Isolate;
31
32namespace internal {
33
34class CppMarkingState;
35class EmbedderStackStateScope;
36class MinorGCHeapGrowing;
37
38// A C++ heap implementation used with V8 to implement unified heap.
41 public v8::CppHeap,
44 public:
47 kReduceMemory = 1 << 1,
48 kForced = 1 << 2,
49 };
50
54
56 public:
57 static constexpr int kMaxBatchedEvents = 16;
58
59 explicit MetricRecorderAdapter(CppHeap& cpp_heap) : cpp_heap_(cpp_heap) {}
60
61 void AddMainThreadEvent(const GCCycle& cppgc_event) final;
62 void AddMainThreadEvent(const MainThreadIncrementalMark& cppgc_event) final;
63 void AddMainThreadEvent(
64 const MainThreadIncrementalSweep& cppgc_event) final;
65
66 void FlushBatchedIncrementalEvents();
67
68 // The following methods are only used for reporting nested cpp events
69 // through V8. Standalone events are reported directly.
70 bool FullGCMetricsReportPending() const;
71 bool YoungGCMetricsReportPending() const;
72
73 const std::optional<cppgc::internal::MetricRecorder::GCCycle>
74 ExtractLastFullGcEvent();
75 const std::optional<cppgc::internal::MetricRecorder::GCCycle>
76 ExtractLastYoungGcEvent();
77 const std::optional<
79 ExtractLastIncrementalMarkEvent();
80
81 void ClearCachedEvents();
82
83 private:
84 Isolate* GetIsolate() const;
85
86 v8::metrics::Recorder::ContextId GetContextId() const;
87
93 std::optional<cppgc::internal::MetricRecorder::GCCycle> last_full_gc_event_;
94 std::optional<cppgc::internal::MetricRecorder::GCCycle>
96 std::optional<cppgc::internal::MetricRecorder::MainThreadIncrementalMark>
98 };
99
100 static void InitializeOncePerProcess();
101
103 return static_cast<CppHeap*>(heap);
104 }
105 static const CppHeap* From(const v8::CppHeap* heap) {
106 return static_cast<const CppHeap*>(heap);
107 }
108
110 const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>&,
112 ~CppHeap() final;
113
114 CppHeap(const CppHeap&) = delete;
115 CppHeap& operator=(const CppHeap&) = delete;
116
117 HeapBase& AsBase() { return *this; }
118 const HeapBase& AsBase() const { return *this; }
119
120 void AttachIsolate(Isolate* isolate);
121 void StartDetachingIsolate();
122 void DetachIsolate();
123
124 void Terminate();
125
126 void CollectCustomSpaceStatisticsAtLastGC(
127 std::vector<cppgc::CustomSpaceIndex>,
128 std::unique_ptr<CustomSpaceStatisticsReceiver>);
129
130 void FinishSweepingIfRunning();
131 void FinishAtomicSweepingIfRunning();
132 void FinishSweepingIfOutOfWork();
133
134 void InitializeMarking(
135 CollectionType,
136 std::shared_ptr<::heap::base::IncrementalMarkingSchedule> schedule = {},
137 GarbageCollectionFlags = GarbageCollectionFlagValues::kNoFlags);
138 void StartMarking();
139 bool AdvanceMarking(v8::base::TimeDelta max_duration,
140 size_t marked_bytes_limit);
141 bool IsMarkingDone() const;
142 size_t last_bytes_marked() const;
143 void ProcessCrossThreadWeakness();
144 void FinishMarkingAndProcessWeakness();
145 void CompactAndSweep();
146 void EnterFinalPause(cppgc::EmbedderStackState stack_state);
147 void EnterProcessGlobalAtomicPause();
148 bool FinishConcurrentMarkingIfNeeded();
149
150 // This method is used to re-enable concurrent marking when the isolate is
151 // moved into the foreground. This method expects that concurrent marking was
152 // not started initially because the isolate was in the background but is
153 // still generally supported.
154 void ReEnableConcurrentMarking();
155
156 void WriteBarrier(void*);
157
158 bool ShouldFinalizeIncrementalMarking() const;
159
160 // StatsCollector::AllocationObserver interface.
161 void AllocatedObjectSizeIncreased(size_t) final;
162 void AllocatedObjectSizeDecreased(size_t) final;
163 void ResetAllocatedObjectSize(size_t) final {}
164
165 MetricRecorderAdapter* GetMetricRecorder() const;
166
167 Isolate* isolate() const { return isolate_; }
168
169 size_t used_size() const {
170 return used_size_.load(std::memory_order_relaxed);
171 }
172 size_t allocated_size() const { return allocated_size_; }
173
174 ::heap::base::Stack* stack() final;
175
176 std::unique_ptr<CppMarkingState> CreateCppMarkingState();
177 std::unique_ptr<CppMarkingState> CreateCppMarkingStateForMutatorThread();
178
179 // cppgc::internal::GarbageCollector interface.
180 void CollectGarbage(cppgc::internal::GCConfig) override;
181
182 std::optional<cppgc::EmbedderStackState> overridden_stack_state()
183 const override;
184 void set_override_stack_state(cppgc::EmbedderStackState state) override;
185 void clear_overridden_stack_state() override;
186
187 void StartIncrementalGarbageCollection(cppgc::internal::GCConfig) override;
188 size_t epoch() const override;
189#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
190 std::optional<int> UpdateAllocationTimeout() final;
191#endif // V8_ENABLE_ALLOCATION_TIMEOUT
192
193 V8_INLINE void RememberCrossHeapReferenceIfNeeded(
195 template <typename F>
196 inline void VisitCrossHeapRememberedSetIfNeeded(F f);
197 void ResetCrossHeapRememberedSet();
198
199 // Testing-only APIs.
200 void EnableDetachedGarbageCollectionsForTesting();
201 void CollectGarbageForTesting(CollectionType, StackState);
202 void UpdateGCCapabilitiesFromFlagsForTesting();
203
204 bool CurrentThreadIsHeapThread() const final;
205
206 private:
207 void UpdateGCCapabilitiesFromFlags();
208
209 void FinalizeIncrementalGarbageCollectionIfNeeded(
210 cppgc::Heap::StackState) final {
211 // For unified heap, CppHeap shouldn't finalize independently (i.e.
212 // finalization is not needed). We only mark marking has done so that V8
213 // can observe that Oilpan is finished.
214 marking_done_ = true;
215 }
216
217 void ReportBufferedAllocationSizeIfPossible();
218
219 void StartIncrementalGarbageCollectionForTesting() final;
220 void FinalizeIncrementalGarbageCollectionForTesting(
221 cppgc::EmbedderStackState) final;
222
223 MarkingType SelectMarkingType() const;
224 SweepingType SelectSweepingType() const;
225
226 bool TracingInitialized() const { return collection_type_.has_value(); }
227
228 bool IsGCForbidden() const override;
229 bool IsGCAllowed() const override;
230 bool IsDetachedGCAllowed() const;
231
232 Heap* heap() const { return heap_; }
233
234 Isolate* isolate_ = nullptr;
235 Heap* heap_ = nullptr;
236 bool marking_done_ = true;
237 // |collection_type_| is initialized when marking is in progress.
238 std::optional<CollectionType> collection_type_;
240
241 std::unique_ptr<MinorGCHeapGrowing> minor_gc_heap_growing_;
243
244 std::unique_ptr<cppgc::internal::Sweeper::SweepingOnMutatorThreadObserver>
246
247 // Buffered allocated bytes. Reporting allocated bytes to V8 can trigger a GC
248 // atomic pause. Allocated bytes are buffer in case this is temporarily
249 // prohibited.
250 int64_t buffered_allocated_bytes_ = 0;
251
252 bool in_detached_testing_mode_ = false;
253 bool force_incremental_marking_for_testing_ = false;
254 bool is_in_v8_marking_step_ = false;
255
256 // Used size of objects. Reported to V8's regular heap growing strategy.
257 std::atomic<size_t> used_size_{0};
258 // Total bytes allocated since the last GC. Monotonically increasing value.
259 // Used to approximate allocation rate.
260 size_t allocated_size_ = 0;
261 // Limit for |allocated_size| in bytes to avoid checking for starting a GC
262 // on each increment.
263 size_t allocated_size_limit_for_check_ = 0;
264
265 std::optional<cppgc::EmbedderStackState> detached_override_stack_state_;
266 std::unique_ptr<v8::internal::EmbedderStackStateScope>
268#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
269 // Use standalone RNG to avoid initialization order dependency.
270 std::optional<v8::base::RandomNumberGenerator> allocation_timeout_rng_;
271#endif // V8_ENABLE_ALLOCATION_TIMEOUT
272
273 bool already_terminated_ = false;
274 bool is_detached_ = true;
275
277};
278
286
287template <typename F>
293
295
296} // namespace internal
297} // namespace v8
298
299#endif // V8_HEAP_CPPGC_JS_CPP_HEAP_H_
Schedule * schedule
Isolate * isolate_
#define F(name, str)
#define DEFINE_OPERATORS_FOR_FLAGS(Type)
Definition flags.h:100
MarkingType
Definition heap.h:60
SweepingType
Definition heap.h:80
bool generational_gc_supported() const
Definition heap-base.h:218
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark incremental_mark_batched_events_
Definition cpp-heap.h:90
std::optional< cppgc::internal::MetricRecorder::GCCycle > last_young_gc_event_
Definition cpp-heap.h:95
std::optional< cppgc::internal::MetricRecorder::MainThreadIncrementalMark > last_incremental_mark_event_
Definition cpp-heap.h:97
std::optional< cppgc::internal::MetricRecorder::GCCycle > last_full_gc_event_
Definition cpp-heap.h:93
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalSweep incremental_sweep_batched_events_
Definition cpp-heap.h:92
std::unique_ptr< MinorGCHeapGrowing > minor_gc_heap_growing_
Definition cpp-heap.h:241
std::optional< cppgc::EmbedderStackState > detached_override_stack_state_
Definition cpp-heap.h:265
GarbageCollectionFlags current_gc_flags_
Definition cpp-heap.h:239
std::optional< CollectionType > collection_type_
Definition cpp-heap.h:238
void ResetAllocatedObjectSize(size_t) final
Definition cpp-heap.h:163
Heap * heap() const
Definition cpp-heap.h:232
V8_INLINE void RememberCrossHeapReferenceIfNeeded(v8::internal::Tagged< v8::internal::JSObject > host_obj, void *value)
Definition cpp-heap.h:279
void VisitCrossHeapRememberedSetIfNeeded(F f)
Definition cpp-heap.h:288
Isolate * isolate() const
Definition cpp-heap.h:167
CrossHeapRememberedSet cross_heap_remembered_set_
Definition cpp-heap.h:242
static CppHeap * From(v8::CppHeap *heap)
Definition cpp-heap.h:102
std::unique_ptr< v8::internal::EmbedderStackStateScope > override_stack_state_scope_
Definition cpp-heap.h:267
size_t allocated_size() const
Definition cpp-heap.h:172
const HeapBase & AsBase() const
Definition cpp-heap.h:118
size_t used_size() const
Definition cpp-heap.h:169
static const CppHeap * From(const v8::CppHeap *heap)
Definition cpp-heap.h:105
std::unique_ptr< cppgc::internal::Sweeper::SweepingOnMutatorThreadObserver > sweeping_on_mutator_thread_observer_
Definition cpp-heap.h:245
void RememberReferenceIfNeeded(Isolate &isolate, Tagged< JSObject > host_obj, void *cppgc_object)
CppHeap::CollectionType collection_type_
Definition cpp-heap.cc:219
ZoneStack< RpoNumber > & stack
cppgc::Heap::StackState StackState
Definition heap-config.h:13
EmbedderStackState
Definition common.h:15
STL namespace.
void Terminate(Isolate *isolate)
Definition bigint.cc:1187
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
Heap * heap_
#define V8_INLINE
Definition v8config.h:500