1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 15:48:12 +00:00

LibJS: Fast non-local variable access :^)

This patch introduces the "environment coordinate" concept, which
encodes the distance from a variable access to the binding it ends up
resolving to.

EnvironmentCoordinate has two fields:

    - hops:  The number of hops up the lexical environment chain we have
             to make before getting to the resolved binding.

    - index: The index of the resolved binding within its declarative
             environment record.

Whenever a variable lookup resolves somewhere inside a declarative
environment, we now cache the coordinates and reuse them in subsequent
lookups. This is achieved via a coordinate cache in JS::Identifier.

Note that non-strict direct eval() breaks this optimization and so it
will not be performed if the resolved environment has been permanently
screwed by eval().

This makes variable access *significantly* faster. :^)
This commit is contained in:
Andreas Kling 2021-10-07 01:06:21 +02:00
parent 421845b0cd
commit 41a072bded
8 changed files with 65 additions and 12 deletions

View file

@ -49,8 +49,8 @@ void Reference::put_value(GlobalObject& global_object, Value value)
VERIFY(m_base_type == BaseType::Environment);
VERIFY(m_base_environment);
if (m_index_in_declarative_environment.has_value())
static_cast<DeclarativeEnvironment*>(m_base_environment)->set_mutable_binding_direct(global_object, m_index_in_declarative_environment.value(), value, m_strict);
if (m_environment_coordinate.has_value())
static_cast<DeclarativeEnvironment*>(m_base_environment)->set_mutable_binding_direct(global_object, m_environment_coordinate->index, value, m_strict);
else
m_base_environment->set_mutable_binding(global_object, m_name.as_string(), value, m_strict);
}
@ -81,8 +81,8 @@ Value Reference::get_value(GlobalObject& global_object) const
VERIFY(m_base_type == BaseType::Environment);
VERIFY(m_base_environment);
if (m_index_in_declarative_environment.has_value())
return static_cast<DeclarativeEnvironment*>(m_base_environment)->get_binding_value_direct(global_object, m_index_in_declarative_environment.value(), m_strict);
if (m_environment_coordinate.has_value())
return static_cast<DeclarativeEnvironment*>(m_base_environment)->get_binding_value_direct(global_object, m_environment_coordinate->index, m_strict);
return m_base_environment->get_binding_value(global_object, m_name.as_string(), m_strict);
}