LibJS: Ensure capacity for created lexical and variable environments

If the minimal amount of required bindings is known in advance, it could
be used to ensure capacity to avoid resizing the internal vector that
holds bindings.
This commit is contained in:
Aliaksandr Kalenik 2024-05-09 17:10:20 +02:00 committed by Andreas Kling
parent a4f70986a0
commit 3d4b13a01c
3 changed files with 16 additions and 5 deletions

View file

@ -120,7 +120,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
}
}
} else {
emit<Op::CreateVariableEnvironment>();
emit<Op::CreateVariableEnvironment>(function.m_var_environment_bindings_count);
if (scope_body) {
for (auto const& variable_to_initialize : function.m_var_names_to_initialize_binding) {
@ -158,7 +158,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
if (!function.m_strict) {
bool can_elide_declarative_environment = !function.m_contains_direct_call_to_eval && (!scope_body || !scope_body->has_non_local_lexical_declarations());
if (!can_elide_declarative_environment) {
emit<Op::CreateLexicalEnvironment>();
emit<Op::CreateLexicalEnvironment>(function.m_lex_environment_bindings_count);
}
}

View file

@ -1256,7 +1256,9 @@ ThrowCompletionOr<void> DeleteVariable::execute_impl(Bytecode::Interpreter& inte
void CreateLexicalEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto make_and_swap_envs = [&](auto& old_environment) {
GCPtr<Environment> environment = new_declarative_environment(*old_environment).ptr();
auto declarative_environment = new_declarative_environment(*old_environment).ptr();
declarative_environment->ensure_capacity(m_capacity);
GCPtr<Environment> environment = declarative_environment;
swap(old_environment, environment);
return environment;
};
@ -1268,6 +1270,7 @@ ThrowCompletionOr<void> CreateVariableEnvironment::execute_impl(Bytecode::Interp
{
auto& running_execution_context = interpreter.vm().running_execution_context();
auto var_environment = new_declarative_environment(*running_execution_context.lexical_environment);
var_environment->ensure_capacity(m_capacity);
running_execution_context.variable_environment = var_environment;
running_execution_context.lexical_environment = var_environment;
return {};

View file

@ -443,24 +443,32 @@ enum class EnvironmentMode {
class CreateLexicalEnvironment final : public Instruction {
public:
explicit CreateLexicalEnvironment()
explicit CreateLexicalEnvironment(u32 capacity = 0)
: Instruction(Type::CreateLexicalEnvironment)
, m_capacity(capacity)
{
}
void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const;
private:
u32 m_capacity { 0 };
};
class CreateVariableEnvironment final : public Instruction {
public:
explicit CreateVariableEnvironment()
explicit CreateVariableEnvironment(u32 capacity = 0)
: Instruction(Type::CreateVariableEnvironment)
, m_capacity(capacity)
{
}
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const;
private:
u32 m_capacity { 0 };
};
class EnterObjectEnvironment final : public Instruction {