Broom 1.0.0
A thread-local C++ Garbage Collector
Loading...
Searching...
No Matches
root-visitor.cc
Go to the documentation of this file.
1#include <stack>
2
3#include "src/allocator.h"
4#include "src/arch/arch-base.h"
6#include "src/roots-inl.h"
7#include "src/roots.h"
8
9namespace broom {
10void RootVisitor::VisitRegularRoot(const void* pointer) {
11 const void* base_pointer =
13 if (base_pointer == nullptr) {
14 return;
15 }
16 // A simple iterative DFS.
17 std::stack<const void*> to_visit;
19 while (!to_visit.empty()) {
20 const void* pointer_to_visit = to_visit.top();
21 to_visit.pop();
22 AllocatorFrontMetadata* metadata = UnsafeCast<AllocatorFrontMetadata*>(
24 // Check if we've already scanned this pointer to avoid cycles and to not
25 // unnecessarily re-scan large parts of the graph.
26 if (metadata->AlreadyScanned()) continue;
27 // If we haven't scanned it yet, mark it as scanned and alive now.
28 metadata->MarkScanned();
31 // Scan to the end, but exclude the metadata at the very end.
32 const void* const* end = SafeCast<const void* const*>(
35 // Go through the allocation and look for pointers that we might want to
36 // visit.
37 for (const void* const* current = SafeCast<const void* const*>(start);
38 current < end; ++current) {
39 const void* maybe_inner = *current;
40 const void* base_pointer =
42 if (base_pointer != nullptr) {
44 }
45 }
46 }
47}
48
50 RootVisitor* visitor, const void* const* stack_bottom,
51 const void* const* stack_top) {
52 BASSERT(IsAligned<kPointerSize>(stack_top), "Stack top is not aligned");
53 BASSERT(IsAligned<kPointerSize>(stack_bottom), "Stack bottom is not aligned");
54 for (const void* const* current = stack_top; current < stack_bottom;
55 ++current) {
56 const void* pointer = *current;
57 if (pointer != nullptr) visitor->Visit<RootKind::kStack>(pointer);
58 }
59}
60
65
66void RootVisitor::VisitStackRoot(const void* maybe_inner) {
67 VisitRegularRoot(maybe_inner);
68}
69
70void RootVisitor::VisitExternalRoot(const ExternalRoot* external_root) {
71 const void* const* end = SafeCast<const void* const*>(
73 const void* const* start = SafeCast<const void* const*>(
74 RoundUp<kPointerSize>(external_root->StartUintPtr()));
75 for (const void* const* current = start; current < end; ++current) {
76 VisitRegularRoot(*current);
77 }
78}
79
80void RootVisitor::VisitPreciseRoot(const PreciseRoot* precise_root) {
81 precise_root->Class()->Visit(SafeCast<Visitor*>(this));
82}
83} // namespace broom
virtual const void * GetBasePointerOfMaybeInnerPointer(const void *maybe_inner) const =0
static constexpr const int kFrontMetadataSize
Definition allocator.h:238
static constexpr const int kBackMetadataSize
Definition allocator.h:240
void MarkAlive(const void *pointer)
void IterateStackAndVisitRoots()
#define BASSERT(x, m,...)
Definition macros.h:57
#define BROOM_NOASAN
Definition macros.h:143
#define BROOM_NOTSAN
Definition macros.h:144
void * GetStackBottom()
BROOM_NOASAN BROOM_NOTSAN BROOM_NOINLINE void IterateStackAndVisitRootsImpl(RootVisitor *visitor, const void *const *stack_bottom, const void *const *stack_top)
uintptr_t UintPtr
Definition globals.h:14
std::queue< T, broom::deque< T > > queue
Definition broom-queue.h:12