From 2bdc69c42c98467d8f114cb6b6b267b5d07851c3 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Fri, 28 Jul 2023 23:59:43 +0200 Subject: [PATCH] LibJS: Add caching of this value in ResolveThisBinding instruction Because "this" value cannot be changed during function execution it is safe to compute it once and then use for future access. This optimization makes ai-astar.js run 8% faster. --- Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | 2 ++ Userland/Libraries/LibJS/Bytecode/Interpreter.h | 3 +++ Userland/Libraries/LibJS/Bytecode/Op.cpp | 9 +++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index c818d9c527..b747ce9b2e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -208,6 +208,8 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Realm& realm, Execu else push_call_frame(make(), executable.number_of_registers); + TemporaryChange restore_this_value { m_this_value, {} }; + for (;;) { Bytecode::InstructionStreamIterator pc(m_current_block->instruction_stream()); TemporaryChange temp_change { m_pc, &pc }; diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.h b/Userland/Libraries/LibJS/Bytecode/Interpreter.h index dfd57fe936..1c4e05883a 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.h +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.h @@ -95,6 +95,8 @@ public: VM::InterpreterExecutionScope ast_interpreter_scope(Realm&); + Optional& this_value() { return m_this_value; } + void visit_edges(Cell::Visitor&); private: @@ -119,6 +121,7 @@ private: Span m_current_call_frame; Optional m_pending_jump; BasicBlock const* m_scheduled_jump { nullptr }; + Optional m_this_value; Optional m_return_value; Optional m_saved_exception; Executable* m_current_executable { nullptr }; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 1e37fd6aee..164ed5b829 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -732,8 +732,13 @@ ThrowCompletionOr Jump::execute_impl(Bytecode::Interpreter& interpreter) c ThrowCompletionOr ResolveThisBinding::execute_impl(Bytecode::Interpreter& interpreter) const { - auto& vm = interpreter.vm(); - interpreter.accumulator() = TRY(vm.resolve_this_binding()); + if (!interpreter.this_value().has_value()) { + // OPTIMIZATION: Because the value of 'this' cannot be reassigned during a function execution, it's + // resolved once and then saved for subsequent use. + auto& vm = interpreter.vm(); + interpreter.this_value() = TRY(vm.resolve_this_binding()); + } + interpreter.accumulator() = interpreter.this_value().value(); return {}; }