blob: 7fcbc1b980b819368047d8f74b58065ca06afef3 [file] [log] [blame]
// 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:
void Traverse(RawHeap* heap) {
if (VisitHeapImpl(heap)) return;
for (auto& space : *heap) {
Traverse(space.get());
}
}
void Traverse(BaseSpace* space) {
const bool is_stopped =
space->is_large()
? VisitLargePageSpaceImpl(LargePageSpace::From(space))
: VisitNormalPageSpaceImpl(NormalPageSpace::From(space));
if (is_stopped) return;
for (auto* page : *space) {
Traverse(page);
}
}
void Traverse(BasePage* page) {
if (page->is_large()) {
auto* large_page = LargePage::From(page);
if (VisitLargePageImpl(large_page)) return;
VisitHeapObjectHeaderImpl(large_page->ObjectHeader());
} else {
auto* normal_page = NormalPage::From(page);
if (VisitNormalPageImpl(normal_page)) return;
for (auto& header : *normal_page) {
VisitHeapObjectHeaderImpl(&header);
}
}
}
protected:
// Visitor functions return true if no deeper processing is required.
// Users are supposed to override functions that need special treatment.
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; }
private:
Derived& ToDerived() { return static_cast<Derived&>(*this); }
bool VisitHeapImpl(RawHeap* heap) { return ToDerived().VisitHeap(heap); }
bool VisitNormalPageSpaceImpl(NormalPageSpace* space) {
return ToDerived().VisitNormalPageSpace(space);
}
bool VisitLargePageSpaceImpl(LargePageSpace* space) {
return ToDerived().VisitLargePageSpace(space);
}
bool VisitNormalPageImpl(NormalPage* page) {
return ToDerived().VisitNormalPage(page);
}
bool VisitLargePageImpl(LargePage* page) {
return ToDerived().VisitLargePage(page);
}
bool VisitHeapObjectHeaderImpl(HeapObjectHeader* hoh) {
return ToDerived().VisitHeapObjectHeader(hoh);
}
};
} // namespace internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_HEAP_VISITOR_H_