heap-visitor.h 2.82 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// 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.

#ifndef V8_HEAP_CPPGC_HEAP_VISITOR_H_
#define V8_HEAP_CPPGC_HEAP_VISITOR_H_

#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap-space.h"
#include "src/heap/cppgc/raw-heap.h"

namespace cppgc {
namespace internal {

// Visitor for heap, which also implements the accept (traverse) interface.
// Implements preorder traversal of the heap. The order of traversal is defined.
// Implemented as a CRTP visitor to avoid virtual calls and support better
// inlining.
template <typename Derived>
class HeapVisitor {
 public:
22
  void Traverse(RawHeap& heap) {
23
    if (VisitHeapImpl(heap)) return;
24 25
    for (auto& space : heap) {
      Traverse(*space.get());
26 27 28
    }
  }

29
  void Traverse(BaseSpace& space) {
30
    const bool is_stopped =
31 32 33
        space.is_large()
            ? VisitLargePageSpaceImpl(LargePageSpace::From(space))
            : VisitNormalPageSpaceImpl(NormalPageSpace::From(space));
34
    if (is_stopped) return;
35 36
    for (auto* page : space) {
      Traverse(*page);
37 38 39
    }
  }

40 41 42 43 44
  void Traverse(BasePage& page) {
    if (page.is_large()) {
      auto* large_page = LargePage::From(&page);
      if (VisitLargePageImpl(*large_page)) return;
      VisitHeapObjectHeaderImpl(*large_page->ObjectHeader());
45
    } else {
46 47
      auto* normal_page = NormalPage::From(&page);
      if (VisitNormalPageImpl(*normal_page)) return;
48
      for (auto& header : *normal_page) {
49
        VisitHeapObjectHeaderImpl(header);
50 51 52 53 54 55 56
      }
    }
  }

 protected:
  // Visitor functions return true if no deeper processing is required.
  // Users are supposed to override functions that need special treatment.
57 58 59 60 61 62
  bool VisitHeap(RawHeap&) { return false; }
  bool VisitNormalPageSpace(NormalPageSpace&) { return false; }
  bool VisitLargePageSpace(LargePageSpace&) { return false; }
  bool VisitNormalPage(NormalPage&) { return false; }
  bool VisitLargePage(LargePage&) { return false; }
  bool VisitHeapObjectHeader(HeapObjectHeader&) { return false; }
63 64 65 66

 private:
  Derived& ToDerived() { return static_cast<Derived&>(*this); }

67 68
  bool VisitHeapImpl(RawHeap& heap) { return ToDerived().VisitHeap(heap); }
  bool VisitNormalPageSpaceImpl(NormalPageSpace& space) {
69 70
    return ToDerived().VisitNormalPageSpace(space);
  }
71
  bool VisitLargePageSpaceImpl(LargePageSpace& space) {
72 73
    return ToDerived().VisitLargePageSpace(space);
  }
74
  bool VisitNormalPageImpl(NormalPage& page) {
75 76
    return ToDerived().VisitNormalPage(page);
  }
77
  bool VisitLargePageImpl(LargePage& page) {
78 79
    return ToDerived().VisitLargePage(page);
  }
80 81
  bool VisitHeapObjectHeaderImpl(HeapObjectHeader& header) {
    return ToDerived().VisitHeapObjectHeader(header);
82 83 84 85 86 87 88
  }
};

}  // namespace internal
}  // namespace cppgc

#endif  // V8_HEAP_CPPGC_HEAP_VISITOR_H_