Commit 11a25229 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Cache scope-info-backed lookup results on entry scope

We'll always lookup variables in the entry scope-info-backed chain through a
single entrypoint, hence we can cache any variables we create in that chain on
the entry-point's VariableMap. Otherwise we always have to redo all negative
lookups until we hit the scope that introduces it (the script scope being the
final possible scope to introduce it).

This should allow us to get rid of the ContextSlotCache as well.

Change-Id: I2dc2c9c35d69f35dab3fe3d0353aba1ac68515a5
Reviewed-on: https://chromium-review.googlesource.com/c/1337729Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57542}
parent b434ee97
......@@ -157,7 +157,7 @@ DeclarationScope::DeclarationScope(Zone* zone,
// Make sure that if we don't find the global 'this', it won't be declared as
// a regular dynamic global by predeclaring it with the right variable kind.
DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE);
DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE, this);
}
DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
......@@ -566,7 +566,7 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
do {
var = query_scope->scope_info_.is_null()
? query_scope->LookupLocal(name)
: query_scope->LookupInScopeInfo(name);
: query_scope->LookupInScopeInfo(name, query_scope);
if (var != nullptr && IsLexical(var)) {
should_hoist = false;
break;
......@@ -920,9 +920,9 @@ void Scope::ReplaceOuterScope(Scope* outer) {
outer_scope_ = outer;
}
Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
DCHECK(!scope_info_.is_null());
Variable* cached = variables_.Lookup(name);
Variable* cached = cache->variables_.Lookup(name);
if (cached) return cached;
Handle<String> name_handle = name->string();
......@@ -968,8 +968,8 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
// TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
// ARGUMENTS bindings as their corresponding VariableKind.
Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
maybe_assigned_flag);
Variable* var = cache->variables_.Declare(zone(), this, name, mode, kind,
init_flag, maybe_assigned_flag);
var->AllocateTo(location, index);
return var;
}
......@@ -1188,10 +1188,11 @@ void Scope::AddUnresolved(VariableProxy* proxy) {
}
Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
VariableKind kind) {
VariableKind kind,
Scope* cache) {
DCHECK(is_script_scope());
return variables_.Declare(zone(), this, name, VariableMode::kDynamicGlobal,
kind);
return cache->variables_.Declare(zone(), this, name,
VariableMode::kDynamicGlobal, kind);
// TODO(neis): Mark variable as maybe-assigned?
}
......@@ -1809,6 +1810,7 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
template <Scope::ScopeLookupMode mode>
Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end, bool force_context_allocation) {
Scope* entry_point = scope;
while (true) {
DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
// Short-cut: whenever we find a debug-evaluate scope, just look everything
......@@ -1824,9 +1826,9 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
}
// Try to find the variable in this scope.
Variable* var = mode == kParsedScope
? scope->LookupLocal(proxy->raw_name())
: scope->LookupInScopeInfo(proxy->raw_name());
Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
: scope->LookupInScopeInfo(
proxy->raw_name(), entry_point);
// We found a variable and we are done. (Even if there is an 'eval' in this
// scope which introduces the same variable again, the resulting variable
......@@ -1869,8 +1871,9 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
if (V8_UNLIKELY(proxy->is_private_name())) return nullptr;
// No binding has been found. Declare a variable on the global object.
return scope->AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(),
NORMAL_VARIABLE);
return scope->AsDeclarationScope()->DeclareDynamicGlobal(
proxy->raw_name(), NORMAL_VARIABLE,
mode == kDeserializedScope ? entry_point : scope);
}
template Variable* Scope::Lookup<Scope::kParsedScope>(
......
......@@ -188,7 +188,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
return variables_.Lookup(name);
}
Variable* LookupInScopeInfo(const AstRawString* name);
Variable* LookupInScopeInfo(const AstRawString* name, Scope* cache);
// Declare a local variable in this scope. If the variable has been
// declared before, the previously declared variable is returned.
......@@ -485,7 +485,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
Variable* var = scope->scope_info_.is_null()
? scope->LookupLocal(name)
: scope->LookupInScopeInfo(name);
: scope->LookupInScopeInfo(name, scope);
if (var != nullptr) return var;
}
return nullptr;
......@@ -709,7 +709,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
Variable* LookupInModule(const AstRawString* name) {
DCHECK(is_module_scope());
Variable* var = LookupInScopeInfo(name);
Variable* var = LookupInScopeInfo(name, this);
DCHECK_NOT_NULL(var);
return var;
}
......@@ -779,7 +779,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// scope) by a reference to an unresolved variable with no intervening
// with statements or eval calls.
Variable* DeclareDynamicGlobal(const AstRawString* name,
VariableKind variable_kind);
VariableKind variable_kind, Scope* cache);
// The variable corresponding to the 'this' value.
Variable* receiver() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment