summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibJS/Heap/Cell.h13
-rw-r--r--Userland/Libraries/LibJS/Heap/Heap.cpp26
-rw-r--r--Userland/Libraries/LibJS/Heap/HeapBlock.cpp4
-rw-r--r--Userland/Libraries/LibJS/Heap/HeapBlock.h9
4 files changed, 32 insertions, 20 deletions
diff --git a/Userland/Libraries/LibJS/Heap/Cell.h b/Userland/Libraries/LibJS/Heap/Cell.h
index d5d61ca442..3074562fac 100644
--- a/Userland/Libraries/LibJS/Heap/Cell.h
+++ b/Userland/Libraries/LibJS/Heap/Cell.h
@@ -26,8 +26,13 @@ public:
bool is_marked() const { return m_mark; }
void set_marked(bool b) { m_mark = b; }
- bool is_live() const { return m_live; }
- void set_live(bool b) { m_live = b; }
+ enum class State {
+ Live,
+ Dead,
+ };
+
+ State state() const { return m_state; }
+ void set_state(State state) { m_state = state; }
virtual const char* class_name() const = 0;
@@ -54,8 +59,8 @@ protected:
Cell() { }
private:
- bool m_mark { false };
- bool m_live { true };
+ bool m_mark : 1 { false };
+ State m_state : 7 { State::Live };
};
}
diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp
index 992c0fa25f..669d5d7b02 100644
--- a/Userland/Libraries/LibJS/Heap/Heap.cpp
+++ b/Userland/Libraries/LibJS/Heap/Heap.cpp
@@ -140,7 +140,7 @@ __attribute__((no_sanitize("address"))) void Heap::gather_conservative_roots(Has
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()) {
+ if (cell->state() == Cell::State::Live) {
dbgln_if(HEAP_DEBUG, " ?-> {}", (const void*)cell);
roots.set(cell);
} else {
@@ -187,19 +187,17 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure
for_each_block([&](auto& block) {
bool block_has_live_cells = false;
bool block_was_full = block.is_full();
- block.for_each_cell([&](Cell* cell) {
- if (cell->is_live()) {
- if (!cell->is_marked()) {
- dbgln_if(HEAP_DEBUG, " ~ {}", cell);
- 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();
- }
+ block.template for_each_cell_in_state<Cell::State::Live>([&](Cell* cell) {
+ if (!cell->is_marked()) {
+ dbgln_if(HEAP_DEBUG, " ~ {}", cell);
+ 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();
}
});
if (!block_has_live_cells)
diff --git a/Userland/Libraries/LibJS/Heap/HeapBlock.cpp b/Userland/Libraries/LibJS/Heap/HeapBlock.cpp
index 97bd82dc58..70ec9ce885 100644
--- a/Userland/Libraries/LibJS/Heap/HeapBlock.cpp
+++ b/Userland/Libraries/LibJS/Heap/HeapBlock.cpp
@@ -47,11 +47,11 @@ void HeapBlock::deallocate(Cell* cell)
{
VERIFY(is_valid_cell_pointer(cell));
VERIFY(!m_freelist || is_valid_cell_pointer(m_freelist));
- VERIFY(cell->is_live());
+ VERIFY(cell->state() == Cell::State::Live);
VERIFY(!cell->is_marked());
cell->~Cell();
auto* freelist_entry = new (cell) FreelistEntry();
- freelist_entry->set_live(false);
+ freelist_entry->set_state(Cell::State::Dead);
freelist_entry->next = m_freelist;
m_freelist = freelist_entry;
}
diff --git a/Userland/Libraries/LibJS/Heap/HeapBlock.h b/Userland/Libraries/LibJS/Heap/HeapBlock.h
index 9472827816..3be74c0158 100644
--- a/Userland/Libraries/LibJS/Heap/HeapBlock.h
+++ b/Userland/Libraries/LibJS/Heap/HeapBlock.h
@@ -48,6 +48,15 @@ public:
callback(cell(i));
}
+ template<Cell::State state, typename Callback>
+ void for_each_cell_in_state(Callback callback)
+ {
+ for_each_cell([&](auto* cell) {
+ if (cell->state() == state)
+ callback(cell);
+ });
+ }
+
Heap& heap() { return m_heap; }
static HeapBlock* from_cell(const Cell* cell)