• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_HEAP_VISITOR_H_
6 #define V8_HEAP_CPPGC_HEAP_VISITOR_H_
7 
8 #include "src/heap/cppgc/heap-page.h"
9 #include "src/heap/cppgc/heap-space.h"
10 #include "src/heap/cppgc/raw-heap.h"
11 
12 namespace cppgc {
13 namespace internal {
14 
15 // Visitor for heap, which also implements the accept (traverse) interface.
16 // Implements preorder traversal of the heap. The order of traversal is defined.
17 // Implemented as a CRTP visitor to avoid virtual calls and support better
18 // inlining.
19 template <typename Derived>
20 class HeapVisitor {
21  public:
Traverse(RawHeap & heap)22   void Traverse(RawHeap& heap) {
23     if (VisitHeapImpl(heap)) return;
24     for (auto& space : heap) {
25       Traverse(*space.get());
26     }
27   }
28 
Traverse(BaseSpace & space)29   void Traverse(BaseSpace& space) {
30     const bool is_stopped =
31         space.is_large()
32             ? VisitLargePageSpaceImpl(LargePageSpace::From(space))
33             : VisitNormalPageSpaceImpl(NormalPageSpace::From(space));
34     if (is_stopped) return;
35     for (auto* page : space) {
36       Traverse(*page);
37     }
38   }
39 
Traverse(BasePage & page)40   void Traverse(BasePage& page) {
41     if (page.is_large()) {
42       auto* large_page = LargePage::From(&page);
43       if (VisitLargePageImpl(*large_page)) return;
44       VisitHeapObjectHeaderImpl(*large_page->ObjectHeader());
45     } else {
46       auto* normal_page = NormalPage::From(&page);
47       if (VisitNormalPageImpl(*normal_page)) return;
48       for (auto& header : *normal_page) {
49         VisitHeapObjectHeaderImpl(header);
50       }
51     }
52   }
53 
54  protected:
55   // Visitor functions return true if no deeper processing is required.
56   // Users are supposed to override functions that need special treatment.
VisitHeap(RawHeap &)57   bool VisitHeap(RawHeap&) { return false; }
VisitNormalPageSpace(NormalPageSpace &)58   bool VisitNormalPageSpace(NormalPageSpace&) { return false; }
VisitLargePageSpace(LargePageSpace &)59   bool VisitLargePageSpace(LargePageSpace&) { return false; }
VisitNormalPage(NormalPage &)60   bool VisitNormalPage(NormalPage&) { return false; }
VisitLargePage(LargePage &)61   bool VisitLargePage(LargePage&) { return false; }
VisitHeapObjectHeader(HeapObjectHeader &)62   bool VisitHeapObjectHeader(HeapObjectHeader&) { return false; }
63 
64  private:
ToDerived()65   Derived& ToDerived() { return static_cast<Derived&>(*this); }
66 
VisitHeapImpl(RawHeap & heap)67   bool VisitHeapImpl(RawHeap& heap) { return ToDerived().VisitHeap(heap); }
VisitNormalPageSpaceImpl(NormalPageSpace & space)68   bool VisitNormalPageSpaceImpl(NormalPageSpace& space) {
69     return ToDerived().VisitNormalPageSpace(space);
70   }
VisitLargePageSpaceImpl(LargePageSpace & space)71   bool VisitLargePageSpaceImpl(LargePageSpace& space) {
72     return ToDerived().VisitLargePageSpace(space);
73   }
VisitNormalPageImpl(NormalPage & page)74   bool VisitNormalPageImpl(NormalPage& page) {
75     return ToDerived().VisitNormalPage(page);
76   }
VisitLargePageImpl(LargePage & page)77   bool VisitLargePageImpl(LargePage& page) {
78     return ToDerived().VisitLargePage(page);
79   }
VisitHeapObjectHeaderImpl(HeapObjectHeader & header)80   bool VisitHeapObjectHeaderImpl(HeapObjectHeader& header) {
81     return ToDerived().VisitHeapObjectHeader(header);
82   }
83 };
84 
85 }  // namespace internal
86 }  // namespace cppgc
87 
88 #endif  // V8_HEAP_CPPGC_HEAP_VISITOR_H_
89