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
This commit is contained in:
Aliaksandr Kalenik 2024-05-23 11:10:23 +01:00 committed by Andreas Kling
commit 63a56a77a2
Notes: sideshowbarker 2024-07-17 04:57:23 +09:00
2 changed files with 30 additions and 1 deletions

View file

@ -13,9 +13,34 @@
namespace JS {
class ExecutionContextAllocator {
public:
NonnullOwnPtr<ExecutionContext> 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<void*> m_execution_contexts;
};
static NeverDestroyed<ExecutionContextAllocator> s_execution_context_allocator;
NonnullOwnPtr<ExecutionContext> 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)

View file

@ -31,11 +31,15 @@ struct ExecutionContext {
void visit_edges(Cell::Visitor&);
private:
friend class ExecutionContextAllocator;
ExecutionContext(Heap&);
IntrusiveListNode<ExecutionContext> m_list_node;
public:
void operator delete(void* ptr);
Heap& m_heap;
using List = IntrusiveList<&ExecutionContext::m_list_node>;