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#include "src/heap/cppgc/marking-visitor.h"
6
7#include "src/heap/cppgc/globals.h"
8#include "src/heap/cppgc/heap.h"
9#include "src/heap/cppgc/marking-state.h"
10
11namespace cppgc {
12namespace internal {
13
14MarkingVisitorBase::MarkingVisitorBase(HeapBase& heap,
15                                       BasicMarkingState& marking_state)
16    : marking_state_(marking_state) {}
17
18void MarkingVisitorBase::Visit(const void* object, TraceDescriptor desc) {
19  marking_state_.MarkAndPush(object, desc);
20}
21
22void MarkingVisitorBase::VisitWeak(const void* object, TraceDescriptor desc,
23                                   WeakCallback weak_callback,
24                                   const void* weak_member) {
25  marking_state_.RegisterWeakReferenceIfNeeded(object, desc, weak_callback,
26                                               weak_member);
27}
28
29void MarkingVisitorBase::VisitEphemeron(const void* key, const void* value,
30                                        TraceDescriptor value_desc) {
31  marking_state_.ProcessEphemeron(key, value, value_desc, *this);
32}
33
34void MarkingVisitorBase::VisitWeakContainer(const void* object,
35                                            TraceDescriptor strong_desc,
36                                            TraceDescriptor weak_desc,
37                                            WeakCallback callback,
38                                            const void* data) {
39  marking_state_.ProcessWeakContainer(object, weak_desc, callback, data);
40}
41
42void MarkingVisitorBase::RegisterWeakCallback(WeakCallback callback,
43                                              const void* object) {
44  marking_state_.RegisterWeakCallback(callback, object);
45}
46
47void MarkingVisitorBase::HandleMovableReference(const void** slot) {
48  marking_state_.RegisterMovableReference(slot);
49}
50
51ConservativeMarkingVisitor::ConservativeMarkingVisitor(
52    HeapBase& heap, MutatorMarkingState& marking_state, cppgc::Visitor& visitor)
53    : ConservativeTracingVisitor(heap, *heap.page_backend(), visitor),
54      marking_state_(marking_state) {}
55
56void ConservativeMarkingVisitor::VisitFullyConstructedConservatively(
57    HeapObjectHeader& header) {
58  if (header.IsMarked<AccessMode::kAtomic>()) {
59    if (marking_state_.IsMarkedWeakContainer(header))
60      marking_state_.ReTraceMarkedWeakContainer(visitor_, header);
61    return;
62  }
63  ConservativeTracingVisitor::VisitFullyConstructedConservatively(header);
64}
65
66void ConservativeMarkingVisitor::VisitInConstructionConservatively(
67    HeapObjectHeader& header, TraceConservativelyCallback callback) {
68  DCHECK(!marking_state_.IsMarkedWeakContainer(header));
69  // In construction objects found through conservative can be marked if they
70  // hold a reference to themselves.
71  if (!marking_state_.MarkNoPush(header)) return;
72  marking_state_.AccountMarkedBytes(header);
73  callback(this, header);
74}
75
76MutatorMarkingVisitor::MutatorMarkingVisitor(HeapBase& heap,
77                                             MutatorMarkingState& marking_state)
78    : MarkingVisitorBase(heap, marking_state) {}
79
80void MutatorMarkingVisitor::VisitRoot(const void* object, TraceDescriptor desc,
81                                      const SourceLocation&) {
82  Visit(object, desc);
83}
84
85void MutatorMarkingVisitor::VisitWeakRoot(const void* object,
86                                          TraceDescriptor desc,
87                                          WeakCallback weak_callback,
88                                          const void* weak_root,
89                                          const SourceLocation&) {
90  static_cast<MutatorMarkingState&>(marking_state_)
91      .InvokeWeakRootsCallbackIfNeeded(object, desc, weak_callback, weak_root);
92}
93
94ConcurrentMarkingVisitor::ConcurrentMarkingVisitor(
95    HeapBase& heap, ConcurrentMarkingState& marking_state)
96    : MarkingVisitorBase(heap, marking_state) {}
97
98void ConservativeMarkingVisitor::VisitPointer(const void* address) {
99  TraceConservativelyIfNeeded(address);
100}
101
102bool ConcurrentMarkingVisitor::DeferTraceToMutatorThreadIfConcurrent(
103    const void* parameter, TraceCallback callback, size_t deferred_size) {
104  marking_state_.concurrent_marking_bailout_worklist().Push(
105      {parameter, callback, deferred_size});
106  static_cast<ConcurrentMarkingState&>(marking_state_)
107      .AccountDeferredMarkedBytes(deferred_size);
108  return true;
109}
110
111}  // namespace internal
112}  // namespace cppgc
113