mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 16:18:12 +00:00
LibJS: Add API for doing GC with a little debug log report at end
You can now pass print_report=true to Heap::collect_garbage() and it will print out a little summary of the time spent, and counts of live vs freed cells and blocks.
This commit is contained in:
parent
6444f49d22
commit
bbd3192535
2 changed files with 31 additions and 5 deletions
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/HashTable.h>
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Heap/HeapBlock.h>
|
||||
|
@ -82,8 +83,10 @@ Cell* Heap::allocate_cell(size_t size)
|
|||
return cell;
|
||||
}
|
||||
|
||||
void Heap::collect_garbage(CollectionType collection_type)
|
||||
void Heap::collect_garbage(CollectionType collection_type, bool print_report)
|
||||
{
|
||||
Core::ElapsedTimer collection_measurement_timer;
|
||||
collection_measurement_timer.start();
|
||||
if (collection_type == CollectionType::CollectGarbage) {
|
||||
if (m_gc_deferrals) {
|
||||
m_should_gc_when_deferral_ends = true;
|
||||
|
@ -93,7 +96,7 @@ void Heap::collect_garbage(CollectionType collection_type)
|
|||
gather_roots(roots);
|
||||
mark_live_cells(roots);
|
||||
}
|
||||
sweep_dead_cells();
|
||||
sweep_dead_cells(print_report, collection_measurement_timer);
|
||||
}
|
||||
|
||||
void Heap::gather_roots(HashTable<Cell*>& roots)
|
||||
|
@ -230,13 +233,18 @@ void Heap::mark_live_cells(const HashTable<Cell*>& roots)
|
|||
visitor.visit(root);
|
||||
}
|
||||
|
||||
void Heap::sweep_dead_cells()
|
||||
void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measurement_timer)
|
||||
{
|
||||
#ifdef HEAP_DEBUG
|
||||
dbg() << "sweep_dead_cells:";
|
||||
#endif
|
||||
Vector<HeapBlock*, 32> empty_blocks;
|
||||
|
||||
size_t collected_cells = 0;
|
||||
size_t live_cells = 0;
|
||||
size_t collected_cell_bytes = 0;
|
||||
size_t live_cell_bytes = 0;
|
||||
|
||||
for (auto& block : m_blocks) {
|
||||
bool block_has_live_cells = false;
|
||||
block->for_each_cell([&](Cell* cell) {
|
||||
|
@ -246,9 +254,13 @@ void Heap::sweep_dead_cells()
|
|||
dbg() << " ~ " << cell;
|
||||
#endif
|
||||
block->deallocate(cell);
|
||||
++collected_cells;
|
||||
collected_cell_bytes += block->cell_size();
|
||||
} else {
|
||||
cell->set_marked(false);
|
||||
block_has_live_cells = true;
|
||||
++live_cells;
|
||||
live_cell_bytes += block->cell_size();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -268,6 +280,19 @@ void Heap::sweep_dead_cells()
|
|||
dbg() << " > Live HeapBlock @ " << block << ": cell_size=" << block->cell_size();
|
||||
}
|
||||
#endif
|
||||
|
||||
int time_spent = measurement_timer.elapsed();
|
||||
|
||||
if (print_report) {
|
||||
dbg() << "Garbage collection report";
|
||||
dbg() << "=============================================";
|
||||
dbg() << " Time spent: " << time_spent << " ms";
|
||||
dbg() << " Live cells: " << live_cells << " (" << live_cell_bytes << " bytes)";
|
||||
dbg() << "Collected cells: " << collected_cells << " (" << collected_cell_bytes << " bytes)";
|
||||
dbg() << " Live blocks: " << m_blocks.size() << " (" << m_blocks.size() * HeapBlock::block_size << " bytes)";
|
||||
dbg() << " Freed blocks: " << empty_blocks.size() << " (" << empty_blocks.size() * HeapBlock::block_size << " bytes)";
|
||||
dbg() << "=============================================";
|
||||
}
|
||||
}
|
||||
|
||||
void Heap::did_create_handle(Badge<HandleImpl>, HandleImpl& impl)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibJS/Runtime/Cell.h>
|
||||
|
@ -68,7 +69,7 @@ public:
|
|||
CollectEverything,
|
||||
};
|
||||
|
||||
void collect_garbage(CollectionType = CollectionType::CollectGarbage);
|
||||
void collect_garbage(CollectionType = CollectionType::CollectGarbage, bool print_report = false);
|
||||
|
||||
Interpreter& interpreter() { return m_interpreter; }
|
||||
|
||||
|
@ -90,7 +91,7 @@ private:
|
|||
void gather_roots(HashTable<Cell*>&);
|
||||
void gather_conservative_roots(HashTable<Cell*>&);
|
||||
void mark_live_cells(const HashTable<Cell*>& live_cells);
|
||||
void sweep_dead_cells();
|
||||
void sweep_dead_cells(bool print_report, const Core::ElapsedTimer&);
|
||||
|
||||
Cell* cell_from_possible_pointer(FlatPtr);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue