From 63a56a77a269f4478cfc647565496ea0ca8647d3 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 23 May 2024 11:10:23 +0100 Subject: [PATCH] LibJS: Add fast ExecutionContext allocator ...that maintains a list of allocated execution contexts so malloc() does not have to be called every time we need to get a new one. 20% improvement in Octane/typescript.js 16% improvement in Kraken/imaging-darkroom.js --- .../LibJS/Runtime/ExecutionContext.cpp | 27 ++++++++++++++++++- .../LibJS/Runtime/ExecutionContext.h | 4 +++ 2 files changed, 30 insertions(+), 1 deletion(-) 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>;