From c541310e1951a86982ba6f212d75f3ea5dddd100 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 7 Oct 2020 14:04:52 +0200 Subject: [PATCH] LibJS: Use IntrusiveList for Allocator's block lists This way we don't need to deal with shifting vector storage, and most operations are upgraded from O(n) to O(1) :^) --- Libraries/LibJS/Heap/Allocator.cpp | 21 +++++++-------------- Libraries/LibJS/Heap/Allocator.h | 11 +++++++---- Libraries/LibJS/Heap/HeapBlock.h | 3 +++ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Libraries/LibJS/Heap/Allocator.cpp b/Libraries/LibJS/Heap/Allocator.cpp index 36dec6132c..03190382c4 100644 --- a/Libraries/LibJS/Heap/Allocator.cpp +++ b/Libraries/LibJS/Heap/Allocator.cpp @@ -42,35 +42,28 @@ Allocator::~Allocator() Cell* Allocator::allocate_cell(Heap& heap) { if (m_usable_blocks.is_empty()) { - m_usable_blocks.append(HeapBlock::create_with_cell_size(heap, m_cell_size)); + auto block = HeapBlock::create_with_cell_size(heap, m_cell_size); + m_usable_blocks.append(*block.leak_ptr()); } auto& block = *m_usable_blocks.last(); auto* cell = block.allocate(); ASSERT(cell); - if (block.is_full()) { - m_full_blocks.append(m_usable_blocks.take_last()); - } + if (block.is_full()) + m_full_blocks.append(*m_usable_blocks.last()); return cell; } void Allocator::block_did_become_empty(Badge, HeapBlock& block) { - bool removed_something = false; - removed_something |= m_full_blocks.remove_first_matching([&block](auto& entry) { return entry == █ }); - removed_something |= m_usable_blocks.remove_first_matching([&block](auto& entry) { return entry == █ }); - ASSERT(removed_something); + block.m_list_node.remove(); + delete █ } void Allocator::block_did_become_usable(Badge, HeapBlock& block) { ASSERT(!block.is_full()); - auto it = m_full_blocks.find([&](auto& entry) { - return entry == █ - }); - ASSERT(it != m_full_blocks.end()); - auto owned_block = m_full_blocks.take(it.index()); - m_usable_blocks.append(move(owned_block)); + m_usable_blocks.append(block); } } diff --git a/Libraries/LibJS/Heap/Allocator.h b/Libraries/LibJS/Heap/Allocator.h index ca2b84cbe8..fd89323de7 100644 --- a/Libraries/LibJS/Heap/Allocator.h +++ b/Libraries/LibJS/Heap/Allocator.h @@ -26,9 +26,11 @@ #pragma once +#include #include #include #include +#include namespace JS { @@ -45,11 +47,11 @@ public: IterationDecision for_each_block(Callback callback) { for (auto& block : m_full_blocks) { - if (callback(*block) == IterationDecision::Break) + if (callback(block) == IterationDecision::Break) return IterationDecision::Break; } for (auto& block : m_usable_blocks) { - if (callback(*block) == IterationDecision::Break) + if (callback(block) == IterationDecision::Break) return IterationDecision::Break; } return IterationDecision::Continue; @@ -61,8 +63,9 @@ public: private: const size_t m_cell_size; - Vector> m_full_blocks; - Vector> m_usable_blocks; + typedef IntrusiveList BlockList; + BlockList m_full_blocks; + BlockList m_usable_blocks; }; } diff --git a/Libraries/LibJS/Heap/HeapBlock.h b/Libraries/LibJS/Heap/HeapBlock.h index 69f991c6bf..f5a3493c57 100644 --- a/Libraries/LibJS/Heap/HeapBlock.h +++ b/Libraries/LibJS/Heap/HeapBlock.h @@ -26,6 +26,7 @@ #pragma once +#include #include #include #include @@ -79,6 +80,8 @@ public: return cell(cell_index); } + IntrusiveListNode m_list_node; + private: HeapBlock(Heap&, size_t cell_size);