mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 03:57:43 +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:
parent
421845b0cd
commit
41a072bded
8 changed files with 65 additions and 12 deletions
|
@ -1005,7 +1005,20 @@ Reference Expression::to_reference(Interpreter&, GlobalObject&) const
|
|||
|
||||
Reference Identifier::to_reference(Interpreter& interpreter, GlobalObject&) const
|
||||
{
|
||||
return interpreter.vm().resolve_binding(string());
|
||||
if (m_cached_environment_coordinate.has_value()) {
|
||||
auto* environment = interpreter.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(), interpreter.vm().in_strict_mode(), m_cached_environment_coordinate };
|
||||
m_cached_environment_coordinate = {};
|
||||
}
|
||||
auto reference = interpreter.vm().resolve_binding(string());
|
||||
if (reference.environment_coordinate().has_value())
|
||||
const_cast<Identifier&>(*this).m_cached_environment_coordinate = reference.environment_coordinate();
|
||||
return reference;
|
||||
}
|
||||
|
||||
Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue