diff --git a/Libraries/LibJS/Heap/HeapBlock.cpp b/Libraries/LibJS/Heap/HeapBlock.cpp index 0e4c9066da..8388934ae4 100644 --- a/Libraries/LibJS/Heap/HeapBlock.cpp +++ b/Libraries/LibJS/Heap/HeapBlock.cpp @@ -61,15 +61,16 @@ HeapBlock::HeapBlock(Heap& heap, size_t cell_size) : m_heap(heap) , m_cell_size(cell_size) { - for (size_t i = 0; i < cell_count(); ++i) { - auto* freelist_entry = static_cast(cell(i)); + ASSERT(cell_size >= sizeof(FreelistEntry)); + + FreelistEntry* next = nullptr; + for (ssize_t i = cell_count() - 1; i >= 0; i--) { + auto* freelist_entry = init_freelist_entry(i); freelist_entry->set_live(false); - if (i == cell_count() - 1) - freelist_entry->next = nullptr; - else - freelist_entry->next = static_cast(cell(i + 1)); + freelist_entry->next = next; + next = freelist_entry; } - m_freelist = static_cast(cell(0)); + m_freelist = next; } Cell* HeapBlock::allocate() @@ -84,7 +85,7 @@ void HeapBlock::deallocate(Cell* cell) ASSERT(cell->is_live()); ASSERT(!cell->is_marked()); cell->~Cell(); - auto* freelist_entry = static_cast(cell); + auto* freelist_entry = new (cell) FreelistEntry(); freelist_entry->set_live(false); freelist_entry->next = m_freelist; m_freelist = freelist_entry; diff --git a/Libraries/LibJS/Heap/HeapBlock.h b/Libraries/LibJS/Heap/HeapBlock.h index ecb1266eb6..8a12d84090 100644 --- a/Libraries/LibJS/Heap/HeapBlock.h +++ b/Libraries/LibJS/Heap/HeapBlock.h @@ -42,8 +42,6 @@ public: size_t cell_size() const { return m_cell_size; } size_t cell_count() const { return (block_size - sizeof(HeapBlock)) / m_cell_size; } - Cell* cell(size_t index) { return reinterpret_cast(&m_storage[index * cell_size()]); } - Cell* allocate(); void deallocate(Cell*); @@ -72,10 +70,22 @@ public: private: HeapBlock(Heap&, size_t cell_size); - struct FreelistEntry : public Cell { - FreelistEntry* next; + struct FreelistEntry final : public Cell { + FreelistEntry* next { nullptr }; + + virtual const char* class_name() const override { return "FreelistEntry"; } }; + Cell* cell(size_t index) + { + return reinterpret_cast(&m_storage[index * cell_size()]); + } + + FreelistEntry* init_freelist_entry(size_t index) + { + return new (&m_storage[index * cell_size()]) FreelistEntry(); + } + Heap& m_heap; size_t m_cell_size { 0 }; FreelistEntry* m_freelist { nullptr };