summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/heap/cppgc/write-barrier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/heap/cppgc/write-barrier.cc')
-rw-r--r--chromium/v8/src/heap/cppgc/write-barrier.cc84
1 files changed, 84 insertions, 0 deletions
diff --git a/chromium/v8/src/heap/cppgc/write-barrier.cc b/chromium/v8/src/heap/cppgc/write-barrier.cc
new file mode 100644
index 00000000000..683a3fc091f
--- /dev/null
+++ b/chromium/v8/src/heap/cppgc/write-barrier.cc
@@ -0,0 +1,84 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "include/cppgc/internal/write-barrier.h"
+
+#include "include/cppgc/internal/pointer-policies.h"
+#include "src/heap/cppgc/globals.h"
+#include "src/heap/cppgc/heap-object-header-inl.h"
+#include "src/heap/cppgc/heap-object-header.h"
+#include "src/heap/cppgc/heap-page-inl.h"
+#include "src/heap/cppgc/heap.h"
+#include "src/heap/cppgc/marker.h"
+#include "src/heap/cppgc/marking-visitor.h"
+
+#if defined(CPPGC_CAGED_HEAP)
+#include "include/cppgc/internal/caged-heap-local-data.h"
+#endif
+
+namespace cppgc {
+namespace internal {
+
+namespace {
+
+void MarkValue(const BasePage* page, Marker* marker, const void* value) {
+#if defined(CPPGC_CAGED_HEAP)
+ DCHECK(reinterpret_cast<CagedHeapLocalData*>(
+ reinterpret_cast<uintptr_t>(value) &
+ ~(kCagedHeapReservationAlignment - 1))
+ ->is_marking_in_progress);
+#endif
+ auto& header =
+ const_cast<HeapObjectHeader&>(page->ObjectHeaderFromInnerAddress(value));
+ if (!header.TryMarkAtomic()) return;
+
+ DCHECK(marker);
+
+ if (V8_UNLIKELY(MutatorThreadMarkingVisitor::IsInConstruction(header))) {
+ // It is assumed that objects on not_fully_constructed_worklist_ are not
+ // marked.
+ header.Unmark();
+ Marker::NotFullyConstructedWorklist::View not_fully_constructed_worklist(
+ marker->not_fully_constructed_worklist(), Marker::kMutatorThreadId);
+ not_fully_constructed_worklist.Push(header.Payload());
+ return;
+ }
+
+ Marker::WriteBarrierWorklist::View write_barrier_worklist(
+ marker->write_barrier_worklist(), Marker::kMutatorThreadId);
+ write_barrier_worklist.Push(&header);
+}
+
+} // namespace
+
+void WriteBarrier::MarkingBarrierSlowWithSentinelCheck(const void* value) {
+ if (!value || value == kSentinelPointer) return;
+
+ MarkingBarrierSlow(value);
+}
+
+void WriteBarrier::MarkingBarrierSlow(const void* value) {
+ const BasePage* page = BasePage::FromPayload(value);
+ const auto* heap = page->heap();
+
+ // Marker being not set up means that no incremental/concurrent marking is in
+ // progress.
+ if (!heap->marker()) return;
+
+ MarkValue(page, heap->marker(), value);
+}
+
+#if defined(CPPGC_YOUNG_GENERATION)
+void WriteBarrier::GenerationalBarrierSlow(CagedHeapLocalData* local_data,
+ const AgeTable& age_table,
+ const void* slot,
+ uintptr_t value_offset) {
+ if (age_table[value_offset] == AgeTable::Age::kOld) return;
+ // Record slot.
+ local_data->heap_base->remembered_slots().insert(const_cast<void*>(slot));
+}
+#endif
+
+} // namespace internal
+} // namespace cppgc