5#ifndef INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
6#define INCLUDE_CPPGC_INTERNAL_WRITE_BARRIER_H_
22#if defined(CPPGC_CAGED_HEAP)
33#if defined(CPPGC_CAGED_HEAP)
34class WriteBarrierTypeForCagedHeapPolicy;
36class WriteBarrierTypeForNonCagedHeapPolicy;
41 enum class Type : uint8_t {
49 kPreciseUncompressedSlot,
56 Type type = Type::kNone;
58#if defined(CPPGC_CAGED_HEAP)
59 uintptr_t slot_offset = 0;
60 uintptr_t value_offset = 0;
70 static V8_INLINE Type GetWriteBarrierType(
const void* slot,
const void* value,
73 template <
typename MemberStorage>
74 static V8_INLINE Type GetWriteBarrierType(
const void* slot, MemberStorage,
77 template <
typename HeapHandleCallback>
78 static V8_INLINE Type GetWriteBarrierType(
const void* slot, Params& params,
79 HeapHandleCallback callback);
81 static V8_INLINE Type GetWriteBarrierType(
const void* value, Params& params);
83#ifdef CPPGC_SLIM_WRITE_BARRIER
87 template <WriteBarrierSlotType>
92 static V8_INLINE void DijkstraMarkingBarrier(
const Params& params,
94 static V8_INLINE void DijkstraMarkingBarrierRange(
95 const Params& params,
const void* first_element,
size_t element_size,
97 static V8_INLINE void SteeleMarkingBarrier(
const Params& params,
99#if defined(CPPGC_YOUNG_GENERATION)
100 template <GenerationalBarrierType>
101 static V8_INLINE void GenerationalBarrier(
const Params& params,
104 template <GenerationalBarrierType>
110 static void CheckParams(Type expected_type,
const Params& params);
118 static bool IsEnabled() {
return write_barrier_enabled_.MightBeEntered(); }
123#if defined(CPPGC_CAGED_HEAP)
124 using WriteBarrierTypePolicy = WriteBarrierTypeForCagedHeapPolicy;
132 DijkstraMarkingBarrierSlowWithSentinelCheck(
const void* value);
134 HeapHandle& heap_handle,
const void* first_element,
size_t element_size,
139 SteeleMarkingBarrierSlowWithSentinelCheck(
const void* value);
141#if defined(CPPGC_YOUNG_GENERATION)
143 const CagedHeapLocalData& local_data,
const AgeTable& age_table,
144 const void* slot, uintptr_t value_offset,
HeapHandle* heap_handle);
146 GenerationalBarrierForUncompressedSlotSlow(
147 const CagedHeapLocalData& local_data,
const AgeTable& age_table,
148 const void* slot, uintptr_t value_offset,
HeapHandle* heap_handle);
150 GenerationalBarrierForSourceObjectSlow(
const CagedHeapLocalData& local_data,
158template <WriteBarrier::Type type>
169#if defined(CPPGC_CAGED_HEAP)
170class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
172 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
173 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void* value,
174 WriteBarrier::Params& params,
175 HeapHandleCallback callback) {
176 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
179 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback,
180 typename MemberStorage>
181 static V8_INLINE WriteBarrier::Type Get(
const void* slot, MemberStorage value,
182 WriteBarrier::Params& params,
183 HeapHandleCallback callback) {
184 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
187 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
188 static V8_INLINE WriteBarrier::Type Get(
const void* value,
189 WriteBarrier::Params& params,
190 HeapHandleCallback callback) {
191 return GetNoSlot(value, params, callback);
195 WriteBarrierTypeForCagedHeapPolicy() =
delete;
197 template <
typename HeapHandleCallback>
198 static V8_INLINE WriteBarrier::Type GetNoSlot(
const void* value,
199 WriteBarrier::Params& params,
200 HeapHandleCallback) {
201 const bool within_cage = CagedHeapBase::IsWithinCage(value);
202 if (!within_cage)
return WriteBarrier::Type::kNone;
206 BasePageHandle* page =
207 BasePageHandle::FromPayload(
const_cast<void*
>(value));
209 HeapHandle& heap_handle = page->heap_handle();
210 if (heap_handle.is_incremental_marking_in_progress()) [[unlikely]] {
211 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
214 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
217 template <WriteBarrier::ValueMode value_mode>
218 struct ValueModeDispatch;
222struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
223 WriteBarrier::ValueMode::kValuePresent> {
224 template <
typename HeapHandleCallback,
typename MemberStorage>
225 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
226 MemberStorage storage,
227 WriteBarrier::Params& params,
228 HeapHandleCallback) {
229 if (!WriteBarrier::IsEnabled()) [[likely]] {
230 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
233 return BarrierEnabledGet(slot, storage.Load(), params);
236 template <
typename HeapHandleCallback>
237 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void* value,
238 WriteBarrier::Params& params,
239 HeapHandleCallback) {
240 if (!WriteBarrier::IsEnabled()) [[likely]] {
241 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
244 return BarrierEnabledGet(slot, value, params);
248 static V8_INLINE WriteBarrier::Type BarrierEnabledGet(
249 const void* slot,
const void* value, WriteBarrier::Params& params) {
250 const bool within_cage = CagedHeapBase::AreWithinCage(slot, value);
251 if (!within_cage)
return WriteBarrier::Type::kNone;
255 BasePageHandle* page =
256 BasePageHandle::FromPayload(
const_cast<void*
>(value));
258 HeapHandle& heap_handle = page->heap_handle();
259 if (!heap_handle.is_incremental_marking_in_progress()) [[likely]] {
260#if defined(CPPGC_YOUNG_GENERATION)
261 if (!heap_handle.is_young_generation_enabled()) {
262 return WriteBarrier::Type::kNone;
264 params.heap = &heap_handle;
265 params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
266 params.value_offset = CagedHeapBase::OffsetFromAddress(value);
267 return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
269 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
274 params.heap = &heap_handle;
275 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
280struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
281 WriteBarrier::ValueMode::kNoValuePresent> {
282 template <
typename HeapHandleCallback>
283 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void*,
284 WriteBarrier::Params& params,
285 HeapHandleCallback callback) {
286 if (!WriteBarrier::IsEnabled()) [[likely]] {
287 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
290 HeapHandle& handle = callback();
291#if defined(CPPGC_YOUNG_GENERATION)
292 if (!handle.is_incremental_marking_in_progress()) [[likely]] {
293 if (!handle.is_young_generation_enabled()) {
294 return WriteBarrier::Type::kNone;
296 params.heap = &handle;
298 if (!CagedHeapBase::IsWithinCage(slot)) [[unlikely]] {
299 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
301 params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
302 return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
305 if (!handle.is_incremental_marking_in_progress()) [[unlikely]] {
306 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
309 params.heap = &handle;
310 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
318 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
321 HeapHandleCallback callback) {
322 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
325 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
328 HeapHandleCallback callback) {
329 return ValueModeDispatch<value_mode>::Get(slot, value.
Load(), params,
333 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
336 HeapHandleCallback callback) {
338 return Get<WriteBarrier::ValueMode::kValuePresent>(
nullptr, value, params,
343 template <WriteBarrier::ValueMode value_mode>
344 struct ValueModeDispatch;
350struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
352 template <
typename HeapHandleCallback>
355 HeapHandleCallback callback) {
358 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
361 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
369 if (heap_handle.is_incremental_marking_in_progress()) [[likely]] {
370 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
372 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
377struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
379 template <
typename HeapHandleCallback>
382 HeapHandleCallback callback) {
385 if (handle.is_incremental_marking_in_progress()) [[likely]] {
386 params.
heap = &handle;
387 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
397 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
402template <
typename MemberStorage>
405 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
410template <
typename HeapHandleCallback>
413 HeapHandleCallback callback) {
414 return WriteBarrierTypePolicy::Get<ValueMode::kNoValuePresent>(
415 slot,
nullptr, params, callback);
421 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(value, params,
427 const void*
object) {
429#if defined(CPPGC_CAGED_HEAP)
431 DijkstraMarkingBarrierSlow(
object);
433 DijkstraMarkingBarrierSlowWithSentinelCheck(
object);
439 const void* first_element,
441 size_t number_of_elements,
444 DijkstraMarkingBarrierRangeSlow(*params.
heap, first_element, element_size,
445 number_of_elements, trace_callback);
450 const void*
object) {
452#if defined(CPPGC_CAGED_HEAP)
454 SteeleMarkingBarrierSlow(
object);
456 SteeleMarkingBarrierSlowWithSentinelCheck(
object);
460#if defined(CPPGC_YOUNG_GENERATION)
463template <WriteBarrier::GenerationalBarrierType type>
467 const CagedHeapLocalData& local_data = CagedHeapLocalData::Get();
468 const AgeTable& age_table = local_data.age_table;
471 if (age_table.GetAge(params.slot_offset) == AgeTable::Age::kYoung)
480 GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset,
482 }
else if constexpr (type ==
484 GenerationalBarrierForUncompressedSlotSlow(
485 local_data, age_table, slot, params.value_offset, params.heap);
487 GenerationalBarrierForSourceObjectSlow(local_data, slot, params.heap);
Definition: heap-handle.h:21
Definition: atomic-entry-flag.h:29
Definition: base-page-handle.h:18
HeapHandle & heap_handle()
Definition: base-page-handle.h:28
static BasePageHandle * FromPayload(void *payload)
Definition: base-page-handle.h:20
Definition: member-storage.h:228
const void * Load() const
Definition: member-storage.h:242
Definition: write-barrier.h:316
static WriteBarrier::Type Get(const void *slot, RawPointer value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:326
static WriteBarrier::Type Get(const void *slot, const void *value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:319
static WriteBarrier::Type Get(const void *value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:334
Definition: write-barrier.h:39
GenerationalBarrierType
Definition: write-barrier.h:47
@ kPreciseUncompressedSlot
static void CheckParams(Type expected_type, const Params ¶ms)
Definition: write-barrier.h:112
Type
Definition: write-barrier.h:41
static Type GetWriteBarrierType(const void *slot, const void *value, Params ¶ms)
Definition: write-barrier.h:395
static void DijkstraMarkingBarrierRange(const Params ¶ms, const void *first_element, size_t element_size, size_t number_of_elements, TraceCallback trace_callback)
Definition: write-barrier.h:438
static void GenerationalBarrier(const Params ¶ms, const void *slot)
Definition: write-barrier.h:105
static bool IsEnabled()
Definition: write-barrier.h:118
static void SteeleMarkingBarrier(const Params ¶ms, const void *object)
Definition: write-barrier.h:449
static void DijkstraMarkingBarrier(const Params ¶ms, const void *object)
Definition: write-barrier.h:426
ValueMode
Definition: write-barrier.h:64
WriteBarrier::Type SetAndReturnType(WriteBarrier::Params ¶ms)
Definition: write-barrier.h:159
Definition: allocation.h:38
void(*)(Visitor *visitor, const void *object) TraceCallback
Definition: trace-trait.h:37
constexpr internal::SentinelPointer kSentinelPointer
Definition: sentinel-pointer.h:35
static WriteBarrier::Type Get(const void *, const void *, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:380
static WriteBarrier::Type Get(const void *, const void *object, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:353
Definition: write-barrier.h:53
HeapHandle * heap
Definition: write-barrier.h:54
#define V8_EXPORT
Definition: v8config.h:867
#define V8_INLINE
Definition: v8config.h:511
#define V8_NOINLINE
Definition: v8config.h:596
#define V8_PRESERVE_MOST
Definition: v8config.h:608