mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibJS: Let invokers (callers) of [[Call]] allocate ExecutionContext
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:
parent
93788f8057
commit
a05be67e4a
Notes:
github-actions[bot]
2025-04-27 23:24:56 +00:00
Author: https://github.com/awesomekling
Commit: a05be67e4a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4497
Reviewed-by: https://github.com/Hendiadyoin1
18 changed files with 139 additions and 84 deletions
|
@ -2616,12 +2616,30 @@ ThrowCompletionOr<void> Call::execute_impl(Bytecode::Interpreter& interpreter) c
|
|||
{
|
||||
auto callee = interpreter.get(m_callee);
|
||||
|
||||
TRY(throw_if_needed_for_call(interpreter, callee, CallType::Call, expression_string()));
|
||||
if (!callee.is_function()) [[unlikely]] {
|
||||
return throw_type_error_for_callee(interpreter, callee, "function"sv, m_expression_string);
|
||||
}
|
||||
|
||||
auto argument_values = interpreter.allocate_argument_values(m_argument_count);
|
||||
for (size_t i = 0; i < m_argument_count; ++i)
|
||||
argument_values[i] = interpreter.get(m_arguments[i]);
|
||||
interpreter.set(dst(), TRY(perform_call(interpreter, interpreter.get(m_this_value), CallType::Call, callee, argument_values)));
|
||||
auto& function = callee.as_function();
|
||||
|
||||
ExecutionContext* callee_context = nullptr;
|
||||
size_t registers_and_constants_and_locals_count = 0;
|
||||
size_t argument_count = m_argument_count;
|
||||
TRY(function.get_stack_frame_size(registers_and_constants_and_locals_count, argument_count));
|
||||
ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK_WITHOUT_CLEARING_ARGS(callee_context, registers_and_constants_and_locals_count, max(m_argument_count, argument_count));
|
||||
|
||||
auto* callee_context_argument_values = callee_context->arguments.data();
|
||||
auto const callee_context_argument_count = callee_context->arguments.size();
|
||||
auto const insn_argument_count = m_argument_count;
|
||||
|
||||
for (size_t i = 0; i < insn_argument_count; ++i)
|
||||
callee_context_argument_values[i] = interpreter.get(m_arguments[i]);
|
||||
for (size_t i = insn_argument_count; i < callee_context_argument_count; ++i)
|
||||
callee_context_argument_values[i] = js_undefined();
|
||||
callee_context->passed_argument_count = insn_argument_count;
|
||||
|
||||
auto retval = TRY(function.internal_call(*callee_context, interpreter.get(m_this_value)));
|
||||
interpreter.set(m_dst, retval);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue