LibJS: Let invokers (callers) of [[Call]] allocate ExecutionContext
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

Instead of letting every [[Call]] implementation allocate an
ExecutionContext, we now make that a responsibility of the caller.

The main point of this exercise is to allow the Call instruction
to write function arguments directly into the callee ExecutionContext
instead of copying them later.

This makes function calls significantly faster:
- 10-20% faster on micro-benchmarks (depending on argument count)
- 4% speedup on Kraken
- 2% speedup on Octane
- 5% speedup on JetStream
This commit is contained in:
Andreas Kling 2025-04-27 11:53:11 +02:00 committed by Andreas Kling
commit a05be67e4a
Notes: github-actions[bot] 2025-04-27 23:24:56 +00:00
18 changed files with 139 additions and 84 deletions

View file

@ -114,7 +114,7 @@ private:
u32 registers_and_constants_and_locals_and_arguments_count { 0 };
};
#define ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK(execution_context, \
#define ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK_WITHOUT_CLEARING_ARGS(execution_context, \
registers_and_constants_and_locals_count, \
arguments_count) \
auto execution_context_size = sizeof(JS::ExecutionContext) \
@ -130,6 +130,16 @@ private:
execution_context->~ExecutionContext(); \
})
#define ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK(execution_context, registers_and_constants_and_locals_count, \
arguments_count) \
ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK_WITHOUT_CLEARING_ARGS(execution_context, \
registers_and_constants_and_locals_count, arguments_count); \
do { \
for (size_t i = 0; i < execution_context->arguments.size(); i++) { \
execution_context->arguments[i] = JS::js_undefined(); \
} \
} while (0)
struct StackTraceElement {
ExecutionContext* execution_context;
RefPtr<CachedSourceRange> source_range;