From ae4e46a0375e55e503b9794a9157e170e4112883 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 7 Oct 2023 18:15:49 +0200 Subject: [PATCH] LibJS: Do less work in successfully cached GetByValue* ops If we have a cached environment coordinate that hasn't been screwed by eval(), we can get the value directly without instantiating a Reference. 15% speed-up on Octane/zlib.js :^) --- .../Libraries/LibJS/Bytecode/Interpreter.cpp | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index ed9800c538b..254e7aa964e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -812,26 +812,23 @@ ThrowCompletionOr GetVariable::execute_impl(Bytecode::Interpreter& interpr { auto& vm = interpreter.vm(); - auto get_reference = [&]() -> ThrowCompletionOr { - auto const& string = interpreter.current_executable().get_identifier(m_identifier); - if (m_cached_environment_coordinate.has_value()) { - auto environment = vm.running_execution_context().lexical_environment; - for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i) - environment = environment->outer_environment(); - VERIFY(environment); - VERIFY(environment->is_declarative_environment()); - if (!environment->is_permanently_screwed_by_eval()) { - return Reference { *environment, string, vm.in_strict_mode(), m_cached_environment_coordinate }; - } - m_cached_environment_coordinate = {}; + if (m_cached_environment_coordinate.has_value()) { + auto environment = vm.running_execution_context().lexical_environment; + for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i) + environment = environment->outer_environment(); + VERIFY(environment); + VERIFY(environment->is_declarative_environment()); + if (!environment->is_permanently_screwed_by_eval()) { + interpreter.accumulator() = TRY(verify_cast(*environment).get_binding_value_direct(vm, m_cached_environment_coordinate.value().index, vm.in_strict_mode())); + return {}; } + m_cached_environment_coordinate = {}; + } - auto reference = TRY(vm.resolve_binding(string)); - if (reference.environment_coordinate().has_value()) - m_cached_environment_coordinate = reference.environment_coordinate(); - return reference; - }; - auto reference = TRY(get_reference()); + auto const& string = interpreter.current_executable().get_identifier(m_identifier); + auto reference = TRY(vm.resolve_binding(string)); + if (reference.environment_coordinate().has_value()) + m_cached_environment_coordinate = reference.environment_coordinate(); interpreter.accumulator() = TRY(reference.get_value(vm)); return {}; } @@ -840,26 +837,28 @@ ThrowCompletionOr GetCalleeAndThisFromEnvironment::execute_impl(Bytecode:: { auto& vm = interpreter.vm(); - auto get_reference = [&]() -> ThrowCompletionOr { - auto const& string = interpreter.current_executable().get_identifier(m_identifier); - if (m_cached_environment_coordinate.has_value()) { - auto environment = vm.running_execution_context().lexical_environment; - for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i) - environment = environment->outer_environment(); - VERIFY(environment); - VERIFY(environment->is_declarative_environment()); - if (!environment->is_permanently_screwed_by_eval()) { - return Reference { *environment, string, vm.in_strict_mode(), m_cached_environment_coordinate }; - } - m_cached_environment_coordinate = {}; + if (m_cached_environment_coordinate.has_value()) { + auto environment = vm.running_execution_context().lexical_environment; + for (size_t i = 0; i < m_cached_environment_coordinate->hops; ++i) + environment = environment->outer_environment(); + VERIFY(environment); + VERIFY(environment->is_declarative_environment()); + if (!environment->is_permanently_screwed_by_eval()) { + interpreter.reg(m_callee_reg) = TRY(verify_cast(*environment).get_binding_value_direct(vm, m_cached_environment_coordinate.value().index, vm.in_strict_mode())); + Value this_value = js_undefined(); + if (auto base_object = environment->with_base_object()) + this_value = base_object; + interpreter.reg(m_this_reg) = this_value; + return {}; } + m_cached_environment_coordinate = {}; + } + + auto const& string = interpreter.current_executable().get_identifier(m_identifier); + auto reference = TRY(vm.resolve_binding(string)); + if (reference.environment_coordinate().has_value()) + m_cached_environment_coordinate = reference.environment_coordinate(); - auto reference = TRY(vm.resolve_binding(string)); - if (reference.environment_coordinate().has_value()) - m_cached_environment_coordinate = reference.environment_coordinate(); - return reference; - }; - auto reference = TRY(get_reference()); interpreter.reg(m_callee_reg) = TRY(reference.get_value(vm)); Value this_value = js_undefined();