[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/1337729 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#57542}
This commit is contained in:
parent
b434ee9795
commit
11a2522933
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user