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:
parent
5dcc58d54a
commit
7826cb2556
2 changed files with 30 additions and 5 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue