diff --git a/Userland/Libraries/LibJS/Runtime/ExecutionContext.cpp b/Userland/Libraries/LibJS/Runtime/ExecutionContext.cpp index 7094d132c57..139f10c401c 100644 --- a/Userland/Libraries/LibJS/Runtime/ExecutionContext.cpp +++ b/Userland/Libraries/LibJS/Runtime/ExecutionContext.cpp @@ -13,9 +13,34 @@ namespace JS { +class ExecutionContextAllocator { +public: + NonnullOwnPtr allocate(Heap& heap) + { + if (m_execution_contexts.is_empty()) + return adopt_own(*new ExecutionContext(heap)); + void* slot = m_execution_contexts.take_last(); + return adopt_own(*new (slot) ExecutionContext(heap)); + } + void deallocate(void* ptr) + { + m_execution_contexts.append(ptr); + } + +private: + Vector m_execution_contexts; +}; + +static NeverDestroyed s_execution_context_allocator; + NonnullOwnPtr ExecutionContext::create(Heap& heap) { - return adopt_own(*new ExecutionContext(heap)); + return s_execution_context_allocator->allocate(heap); +} + +void ExecutionContext::operator delete(void* ptr) +{ + s_execution_context_allocator->deallocate(ptr); } ExecutionContext::ExecutionContext(Heap& heap) diff --git a/Userland/Libraries/LibJS/Runtime/ExecutionContext.h b/Userland/Libraries/LibJS/Runtime/ExecutionContext.h index 4b7694c92ab..81b095f3412 100644 --- a/Userland/Libraries/LibJS/Runtime/ExecutionContext.h +++ b/Userland/Libraries/LibJS/Runtime/ExecutionContext.h @@ -31,11 +31,15 @@ struct ExecutionContext { void visit_edges(Cell::Visitor&); private: + friend class ExecutionContextAllocator; + ExecutionContext(Heap&); IntrusiveListNode m_list_node; public: + void operator delete(void* ptr); + Heap& m_heap; using List = IntrusiveList<&ExecutionContext::m_list_node>;