mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:38:11 +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);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!possible_pointer)
|
||||
continue;
|
||||
#ifdef HEAP_DEBUG
|
||||
dbg() << " ? " << (const void*)possible_pointer;
|
||||
#endif
|
||||
if (auto* cell = cell_from_possible_pointer(possible_pointer)) {
|
||||
if (cell->is_live()) {
|
||||
auto* possible_heap_block = HeapBlock::from_cell(reinterpret_cast<const Cell*>(possible_pointer));
|
||||
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
|
||||
dbg() << " ?-> " << (const void*)cell;
|
||||
dbg() << " ?-> " << (const void*)cell;
|
||||
#endif
|
||||
roots.set(cell);
|
||||
} else {
|
||||
roots.set(cell);
|
||||
} else {
|
||||
#ifdef HEAP_DEBUG
|
||||
dbg() << " #-> " << (const void*)cell;
|
||||
dbg() << " #-> " << (const void*)cell;
|
||||
#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 {
|
||||
public:
|
||||
MarkingVisitor() { }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue