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>
89 CombinedWriteBarrierSlow(
const void* slot);
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;
129 static void DijkstraMarkingBarrierSlow(
const void* value);
130 static void DijkstraMarkingBarrierSlowWithSentinelCheck(
const void* value);
131 static void DijkstraMarkingBarrierRangeSlow(
HeapHandle& heap_handle,
132 const void* first_element,
134 size_t number_of_elements,
136 static void SteeleMarkingBarrierSlow(
const void* value);
137 static void SteeleMarkingBarrierSlowWithSentinelCheck(
const void* value);
139#if defined(CPPGC_YOUNG_GENERATION)
140 static CagedHeapLocalData& GetLocalData(
HeapHandle&);
141 static void GenerationalBarrierSlow(
const CagedHeapLocalData& local_data,
142 const AgeTable& age_table,
143 const void* slot, uintptr_t value_offset,
145 static void GenerationalBarrierForUncompressedSlotSlow(
146 const CagedHeapLocalData& local_data,
const AgeTable& age_table,
147 const void* slot, uintptr_t value_offset,
HeapHandle* heap_handle);
148 static void GenerationalBarrierForSourceObjectSlow(
149 const CagedHeapLocalData& local_data,
const void*
object,
156template <WriteBarrier::Type type>
167#if defined(CPPGC_CAGED_HEAP)
168class V8_EXPORT WriteBarrierTypeForCagedHeapPolicy final {
170 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
171 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void* value,
172 WriteBarrier::Params& params,
173 HeapHandleCallback callback) {
174 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
177 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback,
178 typename MemberStorage>
179 static V8_INLINE WriteBarrier::Type Get(
const void* slot, MemberStorage value,
180 WriteBarrier::Params& params,
181 HeapHandleCallback callback) {
182 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
185 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
186 static V8_INLINE WriteBarrier::Type Get(
const void* value,
187 WriteBarrier::Params& params,
188 HeapHandleCallback callback) {
189 return GetNoSlot(value, params, callback);
193 WriteBarrierTypeForCagedHeapPolicy() =
delete;
195 template <
typename HeapHandleCallback>
196 static V8_INLINE WriteBarrier::Type GetNoSlot(
const void* value,
197 WriteBarrier::Params& params,
198 HeapHandleCallback) {
199 const bool within_cage = CagedHeapBase::IsWithinCage(value);
200 if (!within_cage)
return WriteBarrier::Type::kNone;
204 BasePageHandle* page =
205 BasePageHandle::FromPayload(
const_cast<void*
>(value));
207 HeapHandle& heap_handle = page->heap_handle();
208 if (
V8_UNLIKELY(heap_handle.is_incremental_marking_in_progress())) {
209 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
212 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
215 template <WriteBarrier::ValueMode value_mode>
216 struct ValueModeDispatch;
220struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
221 WriteBarrier::ValueMode::kValuePresent> {
222 template <
typename HeapHandleCallback,
typename MemberStorage>
223 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
224 MemberStorage storage,
225 WriteBarrier::Params& params,
226 HeapHandleCallback) {
227 if (
V8_LIKELY(!WriteBarrier::IsEnabled())) {
228 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
231 return BarrierEnabledGet(slot, storage.Load(), params);
234 template <
typename HeapHandleCallback>
235 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void* value,
236 WriteBarrier::Params& params,
237 HeapHandleCallback) {
238 if (
V8_LIKELY(!WriteBarrier::IsEnabled())) {
239 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
242 return BarrierEnabledGet(slot, value, params);
246 static V8_INLINE WriteBarrier::Type BarrierEnabledGet(
247 const void* slot,
const void* value, WriteBarrier::Params& params) {
248 const bool within_cage = CagedHeapBase::AreWithinCage(slot, value);
249 if (!within_cage)
return WriteBarrier::Type::kNone;
253 BasePageHandle* page =
254 BasePageHandle::FromPayload(
const_cast<void*
>(value));
256 HeapHandle& heap_handle = page->heap_handle();
257 if (
V8_LIKELY(!heap_handle.is_incremental_marking_in_progress())) {
258#if defined(CPPGC_YOUNG_GENERATION)
259 if (!heap_handle.is_young_generation_enabled()) {
260 return WriteBarrier::Type::kNone;
262 params.heap = &heap_handle;
263 params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
264 params.value_offset = CagedHeapBase::OffsetFromAddress(value);
265 return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
267 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
272 params.heap = &heap_handle;
273 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
278struct WriteBarrierTypeForCagedHeapPolicy::ValueModeDispatch<
279 WriteBarrier::ValueMode::kNoValuePresent> {
280 template <
typename HeapHandleCallback>
281 static V8_INLINE WriteBarrier::Type Get(
const void* slot,
const void*,
282 WriteBarrier::Params& params,
283 HeapHandleCallback callback) {
284 if (
V8_LIKELY(!WriteBarrier::IsEnabled())) {
285 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
288 HeapHandle& handle = callback();
289#if defined(CPPGC_YOUNG_GENERATION)
290 if (
V8_LIKELY(!handle.is_incremental_marking_in_progress())) {
291 if (!handle.is_young_generation_enabled()) {
292 return WriteBarrier::Type::kNone;
294 params.heap = &handle;
296 if (
V8_UNLIKELY(!CagedHeapBase::IsWithinCage(slot))) {
297 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
299 params.slot_offset = CagedHeapBase::OffsetFromAddress(slot);
300 return SetAndReturnType<WriteBarrier::Type::kGenerational>(params);
303 if (
V8_UNLIKELY(!handle.is_incremental_marking_in_progress())) {
304 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
307 params.heap = &handle;
308 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
316 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
319 HeapHandleCallback callback) {
320 return ValueModeDispatch<value_mode>::Get(slot, value, params, callback);
323 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
326 HeapHandleCallback callback) {
327 return ValueModeDispatch<value_mode>::Get(slot, value.
Load(), params,
331 template <WriteBarrier::ValueMode value_mode,
typename HeapHandleCallback>
334 HeapHandleCallback callback) {
336 return Get<WriteBarrier::ValueMode::kValuePresent>(
nullptr, value, params,
341 template <WriteBarrier::ValueMode value_mode>
342 struct ValueModeDispatch;
348struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
350 template <
typename HeapHandleCallback>
353 HeapHandleCallback callback) {
356 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
359 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
367 if (
V8_LIKELY(heap_handle.is_incremental_marking_in_progress())) {
368 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
370 return SetAndReturnType<WriteBarrier::Type::kNone>(params);
375struct WriteBarrierTypeForNonCagedHeapPolicy::ValueModeDispatch<
377 template <
typename HeapHandleCallback>
380 HeapHandleCallback callback) {
383 if (
V8_LIKELY(handle.is_incremental_marking_in_progress())) {
384 params.
heap = &handle;
385 return SetAndReturnType<WriteBarrier::Type::kMarking>(params);
395 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
400template <
typename MemberStorage>
403 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(slot, value,
408template <
typename HeapHandleCallback>
411 HeapHandleCallback callback) {
412 return WriteBarrierTypePolicy::Get<ValueMode::kNoValuePresent>(
413 slot,
nullptr, params, callback);
419 return WriteBarrierTypePolicy::Get<ValueMode::kValuePresent>(value, params,
425 const void*
object) {
427#if defined(CPPGC_CAGED_HEAP)
429 DijkstraMarkingBarrierSlow(
object);
431 DijkstraMarkingBarrierSlowWithSentinelCheck(
object);
437 const void* first_element,
439 size_t number_of_elements,
442 DijkstraMarkingBarrierRangeSlow(*params.
heap, first_element, element_size,
443 number_of_elements, trace_callback);
448 const void*
object) {
450#if defined(CPPGC_CAGED_HEAP)
452 SteeleMarkingBarrierSlow(
object);
454 SteeleMarkingBarrierSlowWithSentinelCheck(
object);
458#if defined(CPPGC_YOUNG_GENERATION)
461template <WriteBarrier::GenerationalBarrierType type>
465 const CagedHeapLocalData& local_data = CagedHeapLocalData::Get();
466 const AgeTable& age_table = local_data.age_table;
469 if (
V8_LIKELY(age_table.GetAge(params.slot_offset) ==
470 AgeTable::Age::kYoung)) {
478 GenerationalBarrierSlow(local_data, age_table, slot, params.value_offset,
480 }
else if constexpr (type ==
482 GenerationalBarrierForUncompressedSlotSlow(
483 local_data, age_table, slot, params.value_offset, params.heap);
485 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:314
static WriteBarrier::Type Get(const void *slot, RawPointer value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:324
static WriteBarrier::Type Get(const void *slot, const void *value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:317
static WriteBarrier::Type Get(const void *value, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:332
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:393
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:436
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:447
static void DijkstraMarkingBarrier(const Params ¶ms, const void *object)
Definition: write-barrier.h:424
ValueMode
Definition: write-barrier.h:64
WriteBarrier::Type SetAndReturnType(WriteBarrier::Params ¶ms)
Definition: write-barrier.h:157
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:378
static WriteBarrier::Type Get(const void *, const void *object, WriteBarrier::Params ¶ms, HeapHandleCallback callback)
Definition: write-barrier.h:351
Definition: write-barrier.h:53
HeapHandle * heap
Definition: write-barrier.h:54
#define V8_EXPORT
Definition: v8config.h:854
#define V8_INLINE
Definition: v8config.h:508
#define V8_LIKELY(condition)
Definition: v8config.h:668
#define V8_UNLIKELY(condition)
Definition: v8config.h:667
#define V8_NOINLINE
Definition: v8config.h:593
#define V8_PRESERVE_MOST
Definition: v8config.h:605