mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:17:45 +00:00
LibJS: Use a HashTable to identify potential cell pointers in GC scan
Previously we would iterate over all the live HeapBlocks in order to learn if an arbitrary pointer-sized value was a pointer into a live HeapBlock. This was quite time-consuming. Instead of that, just put all the live HeapBlock*'s in a HashTable and identify pointers by doing a bit-masked lookup into the table.
This commit is contained in:
parent
50aa726db7
commit
1745e503aa
2 changed files with 15 additions and 24 deletions
|
@ -151,43 +151,36 @@ void Heap::gather_conservative_roots(HashTable<Cell*>& roots)
|
||||||
possible_pointers.set(data);
|
possible_pointers.set(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashTable<HeapBlock*> all_live_heap_blocks;
|
||||||
|
for_each_block([&](auto& block) {
|
||||||
|
all_live_heap_blocks.set(&block);
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
for (auto possible_pointer : possible_pointers) {
|
for (auto possible_pointer : possible_pointers) {
|
||||||
if (!possible_pointer)
|
if (!possible_pointer)
|
||||||
continue;
|
continue;
|
||||||
#ifdef HEAP_DEBUG
|
#ifdef HEAP_DEBUG
|
||||||
dbg() << " ? " << (const void*)possible_pointer;
|
dbg() << " ? " << (const void*)possible_pointer;
|
||||||
#endif
|
#endif
|
||||||
if (auto* cell = cell_from_possible_pointer(possible_pointer)) {
|
auto* possible_heap_block = HeapBlock::from_cell(reinterpret_cast<const Cell*>(possible_pointer));
|
||||||
if (cell->is_live()) {
|
if (all_live_heap_blocks.contains(possible_heap_block)) {
|
||||||
|
if (auto* cell = possible_heap_block->cell_from_possible_pointer(possible_pointer)) {
|
||||||
|
if (cell->is_live()) {
|
||||||
#ifdef HEAP_DEBUG
|
#ifdef HEAP_DEBUG
|
||||||
dbg() << " ?-> " << (const void*)cell;
|
dbg() << " ?-> " << (const void*)cell;
|
||||||
#endif
|
#endif
|
||||||
roots.set(cell);
|
roots.set(cell);
|
||||||
} else {
|
} else {
|
||||||
#ifdef HEAP_DEBUG
|
#ifdef HEAP_DEBUG
|
||||||
dbg() << " #-> " << (const void*)cell;
|
dbg() << " #-> " << (const void*)cell;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cell* Heap::cell_from_possible_pointer(FlatPtr pointer)
|
|
||||||
{
|
|
||||||
auto* possible_heap_block = HeapBlock::from_cell(reinterpret_cast<const Cell*>(pointer));
|
|
||||||
bool found = false;
|
|
||||||
for_each_block([&](auto& block) {
|
|
||||||
if (&block == possible_heap_block) {
|
|
||||||
found = true;
|
|
||||||
return IterationDecision::Break;
|
|
||||||
}
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
if (!found)
|
|
||||||
return nullptr;
|
|
||||||
return possible_heap_block->cell_from_possible_pointer(pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
class MarkingVisitor final : public Cell::Visitor {
|
class MarkingVisitor final : public Cell::Visitor {
|
||||||
public:
|
public:
|
||||||
MarkingVisitor() { }
|
MarkingVisitor() { }
|
||||||
|
|
|
@ -100,8 +100,6 @@ private:
|
||||||
void mark_live_cells(const HashTable<Cell*>& live_cells);
|
void mark_live_cells(const HashTable<Cell*>& live_cells);
|
||||||
void sweep_dead_cells(bool print_report, const Core::ElapsedTimer&);
|
void sweep_dead_cells(bool print_report, const Core::ElapsedTimer&);
|
||||||
|
|
||||||
Cell* cell_from_possible_pointer(FlatPtr);
|
|
||||||
|
|
||||||
Allocator& allocator_for_size(size_t);
|
Allocator& allocator_for_size(size_t);
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue