Skip to content

Commit

Permalink
LibJS: Add fast ExecutionContext allocator
Browse files Browse the repository at this point in the history
...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
  • Loading branch information
kalenikaliaksandr committed May 23, 2024
1 parent a68222f commit ea435f5
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
35 changes: 34 additions & 1 deletion Userland/Libraries/LibJS/Runtime/ExecutionContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,42 @@

namespace JS {

class ExecutionContextAllocator {
public:
NonnullOwnPtr<ExecutionContext> allocate(Heap& heap)
{
if (m_execution_contexts.is_empty())
return adopt_own(*new ExecutionContext(heap));
return m_execution_contexts.take_last();
}
void deallocate(ExecutionContext* ec)
{
if (m_destroyed)
return;
memset(ec, 0, sizeof(ExecutionContext));
m_execution_contexts.append(adopt_own(*ec));
}

~ExecutionContextAllocator()
{
m_destroyed = true;
}

private:
Vector<NonnullOwnPtr<ExecutionContext>> m_execution_contexts;
bool m_destroyed { false };
};

static 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(static_cast<ExecutionContext*>(ptr));
}

ExecutionContext::ExecutionContext(Heap& heap)
Expand Down
4 changes: 4 additions & 0 deletions Userland/Libraries/LibJS/Runtime/ExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down

0 comments on commit ea435f5

Please sign in to comment.