/* * Copyright (c) 2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #define JS_DECLARE_ALLOCATOR(ClassName) \ static JS::TypeIsolatingCellAllocator cell_allocator; #define JS_DEFINE_ALLOCATOR(ClassName) \ JS::TypeIsolatingCellAllocator ClassName::cell_allocator; namespace JS { class CellAllocator { public: explicit CellAllocator(size_t cell_size); ~CellAllocator() = default; size_t cell_size() const { return m_cell_size; } Cell* allocate_cell(Heap&); template IterationDecision for_each_block(Callback callback) { for (auto& block : m_full_blocks) { if (callback(block) == IterationDecision::Break) return IterationDecision::Break; } for (auto& block : m_usable_blocks) { if (callback(block) == IterationDecision::Break) return IterationDecision::Break; } return IterationDecision::Continue; } void block_did_become_empty(Badge, HeapBlock&); void block_did_become_usable(Badge, HeapBlock&); private: size_t const m_cell_size; using BlockList = IntrusiveList<&HeapBlock::m_list_node>; BlockList m_full_blocks; BlockList m_usable_blocks; }; template class TypeIsolatingCellAllocator { public: using CellType = T; CellAllocator allocator { sizeof(T) }; }; }