mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:07:44 +00:00
LibJS: Add a finalization pass to the garbage collector
Doing things in the destructor of a GC-allocated object isn't always safe, in case it involves accessing other GC-allocated objects. If they were already swept by GC, we'd be poking into freed memory. This patch adds a separate finalization pass where GC calls finalize() on every unmarked cell that's about to be deleted. It's safe to access other GC objects in finalize(), even if they're also unmarked.
This commit is contained in:
parent
6d830e6335
commit
07a36c8f80
3 changed files with 16 additions and 0 deletions
|
@ -106,6 +106,7 @@ void Heap::collect_garbage(CollectionType collection_type, bool print_report)
|
|||
gather_roots(roots);
|
||||
mark_live_cells(roots);
|
||||
}
|
||||
finalize_unmarked_cells();
|
||||
sweep_dead_cells(print_report, collection_measurement_timer);
|
||||
}
|
||||
|
||||
|
@ -231,6 +232,17 @@ void Heap::mark_live_cells(HashTable<Cell*> const& roots)
|
|||
m_uprooted_cells.clear();
|
||||
}
|
||||
|
||||
void Heap::finalize_unmarked_cells()
|
||||
{
|
||||
for_each_block([&](auto& block) {
|
||||
block.template for_each_cell_in_state<Cell::State::Live>([](Cell* cell) {
|
||||
if (!cell->is_marked())
|
||||
cell->finalize();
|
||||
});
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
void Heap::sweep_dead_cells(bool print_report, Core::ElapsedTimer const& measurement_timer)
|
||||
{
|
||||
dbgln_if(HEAP_DEBUG, "sweep_dead_cells:");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue