1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:47:45 +00:00

LibJS: Use a work queue instead of the C++ stack for the GC mark phase

This fixes an issue where we'd run out of C++ stack while traversing
large GC heap graphs.
This commit is contained in:
Andreas Kling 2023-01-10 20:17:29 +01:00 committed by Tim Flynn
parent 5dcc58d54a
commit 7826cb2556
2 changed files with 30 additions and 5 deletions

View file

@ -208,7 +208,12 @@ __attribute__((no_sanitize("address"))) void Heap::gather_conservative_roots(Has
class MarkingVisitor final : public Cell::Visitor {
public:
MarkingVisitor() = default;
explicit MarkingVisitor(HashTable<Cell*> const& roots)
{
for (auto* root : roots) {
visit(root);
}
}
virtual void visit_impl(Cell& cell) override
{
@ -217,17 +222,26 @@ public:
dbgln_if(HEAP_DEBUG, " ! {}", &cell);
cell.set_marked(true);
cell.visit_edges(*this);
m_work_queue.append(cell);
}
void mark_all_live_cells()
{
while (!m_work_queue.is_empty()) {
m_work_queue.take_last().visit_edges(*this);
}
}
private:
Vector<Cell&> m_work_queue;
};
void Heap::mark_live_cells(HashTable<Cell*> const& roots)
{
dbgln_if(HEAP_DEBUG, "mark_live_cells:");
MarkingVisitor visitor;
for (auto* root : roots)
visitor.visit(root);
MarkingVisitor visitor(roots);
visitor.mark_all_live_cells();
for (auto& inverse_root : m_uprooted_cells)
inverse_root->set_marked(false);