Skip to content

Commit

Permalink
LibJS: Use a HashTable to identify potential cell pointers in GC scan
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
awesomekling committed Nov 10, 2020
1 parent 50aa726 commit 1745e50
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 24 deletions.
37 changes: 15 additions & 22 deletions Libraries/LibJS/Heap/Heap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() { }
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibJS/Heap/Heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ class Heap {
void mark_live_cells(const HashTable<Cell*>& live_cells);
void sweep_dead_cells(bool print_report, const Core::ElapsedTimer&);

Cell* cell_from_possible_pointer(FlatPtr);

Allocator& allocator_for_size(size_t);

template<typename Callback>
Expand Down

0 comments on commit 1745e50

Please sign in to comment.