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_UNIFIED_HEAP_MARKING_VISITOR_H_
6#define V8_HEAP_CPPGC_JS_UNIFIED_HEAP_MARKING_VISITOR_H_
7
8#include "include/cppgc/trace-trait.h"
9#include "include/v8-cppgc.h"
10#include "src/base/macros.h"
11#include "src/heap/cppgc-js/unified-heap-marking-state.h"
12#include "src/heap/cppgc/marking-visitor.h"
13
14namespace cppgc {
15
16class SourceLocation;
17
18namespace internal {
19class ConcurrentMarkingState;
20class BasicMarkingState;
21class MutatorMarkingState;
22}  // namespace internal
23}  // namespace cppgc
24
25namespace v8 {
26namespace internal {
27
28using cppgc::SourceLocation;
29using cppgc::TraceDescriptor;
30using cppgc::WeakCallback;
31using cppgc::internal::HeapBase;
32using cppgc::internal::MutatorMarkingState;
33
34class UnifiedHeapMarker;
35
36class V8_EXPORT_PRIVATE UnifiedHeapMarkingVisitorBase : public JSVisitor {
37 public:
38  UnifiedHeapMarkingVisitorBase(HeapBase&, cppgc::internal::BasicMarkingState&,
39                                UnifiedHeapMarkingState&);
40  ~UnifiedHeapMarkingVisitorBase() override = default;
41
42 protected:
43  // C++ handling.
44  void Visit(const void*, TraceDescriptor) final;
45  void VisitWeak(const void*, TraceDescriptor, WeakCallback, const void*) final;
46  void VisitEphemeron(const void*, const void*, TraceDescriptor) final;
47  void VisitWeakContainer(const void* self, TraceDescriptor strong_desc,
48                          TraceDescriptor weak_desc, WeakCallback callback,
49                          const void* data) final;
50  void RegisterWeakCallback(WeakCallback, const void*) final;
51  void HandleMovableReference(const void**) final;
52
53  // JS handling.
54  void Visit(const TracedReferenceBase& ref) override;
55
56  cppgc::internal::BasicMarkingState& marking_state_;
57  UnifiedHeapMarkingState& unified_heap_marking_state_;
58
59  friend class UnifiedHeapMarker;
60};
61
62class V8_EXPORT_PRIVATE MutatorUnifiedHeapMarkingVisitor
63    : public UnifiedHeapMarkingVisitorBase {
64 public:
65  MutatorUnifiedHeapMarkingVisitor(HeapBase&, MutatorMarkingState&,
66                                   UnifiedHeapMarkingState&);
67  ~MutatorUnifiedHeapMarkingVisitor() override = default;
68
69 protected:
70  void VisitRoot(const void*, TraceDescriptor, const SourceLocation&) final;
71  void VisitWeakRoot(const void*, TraceDescriptor, WeakCallback, const void*,
72                     const SourceLocation&) final;
73};
74
75class V8_EXPORT_PRIVATE MutatorMinorGCMarkingVisitor final
76    : public MutatorUnifiedHeapMarkingVisitor {
77 public:
78  using MutatorUnifiedHeapMarkingVisitor::MutatorUnifiedHeapMarkingVisitor;
79  ~MutatorMinorGCMarkingVisitor() override = default;
80
81 protected:
82  // Override and make the function empty, since we don't want to trace V8
83  // reference during cppgc's minor GC.
84  void Visit(const TracedReferenceBase&) final {}
85};
86
87class V8_EXPORT_PRIVATE ConcurrentUnifiedHeapMarkingVisitor final
88    : public UnifiedHeapMarkingVisitorBase {
89 public:
90  ConcurrentUnifiedHeapMarkingVisitor(HeapBase&, Heap*,
91                                      cppgc::internal::ConcurrentMarkingState&);
92  ~ConcurrentUnifiedHeapMarkingVisitor() override;
93
94 protected:
95  void VisitRoot(const void*, TraceDescriptor, const SourceLocation&) final {
96    UNREACHABLE();
97  }
98  void VisitWeakRoot(const void*, TraceDescriptor, WeakCallback, const void*,
99                     const SourceLocation&) final {
100    UNREACHABLE();
101  }
102
103  bool DeferTraceToMutatorThreadIfConcurrent(const void*, cppgc::TraceCallback,
104                                             size_t) final;
105
106 private:
107  // Visitor owns the local worklist. All remaining items are published on
108  // destruction of the visitor. This is good enough as concurrent visitation
109  // ends before computing the rest of the transitive closure on the main
110  // thread. Dynamically allocated as it is only present when the heaps are
111  // attached.
112  std::unique_ptr<MarkingWorklists::Local> local_marking_worklist_;
113  UnifiedHeapMarkingState concurrent_unified_heap_marking_state_;
114};
115
116}  // namespace internal
117}  // namespace v8
118
119#endif  // V8_HEAP_CPPGC_JS_UNIFIED_HEAP_MARKING_VISITOR_H_
120