Index: src/ast/scopes.cc |
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc |
index ce293662e9a84c90f7ecee12962ba7f993951ad0..34deb59c64e6dd8eb1648908b5834c1ff8c50c09 100644 |
--- a/src/ast/scopes.cc |
+++ b/src/ast/scopes.cc |
@@ -115,7 +115,6 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
force_context_allocation_ = |
!is_function_scope() && outer_scope->has_forced_context_allocation(); |
outer_scope_->AddInnerScope(this); |
- if (outer_scope_->is_lazily_parsed_) is_lazily_parsed_ = true; |
} |
Scope::Snapshot::Snapshot(Scope* scope) |
@@ -278,6 +277,7 @@ void Scope::SetDefaults() { |
#ifdef DEBUG |
scope_name_ = nullptr; |
already_resolved_ = false; |
+ needs_migration_ = false; |
#endif |
inner_scope_ = nullptr; |
sibling_ = nullptr; |
@@ -953,7 +953,7 @@ VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
// the same name because they may be removed selectively via |
// RemoveUnresolved(). |
DCHECK(!already_resolved_); |
- DCHECK_EQ(factory->zone(), zone()); |
+ DCHECK_EQ(!needs_migration_, factory->zone() == zone()); |
VariableProxy* proxy = |
factory->NewVariableProxy(name, kind, start_position, end_position); |
proxy->set_next_unresolved(unresolved_); |
@@ -1212,42 +1212,42 @@ void DeclarationScope::ResetAfterPreparsing(bool aborted) { |
} |
} else { |
params_.Clear(); |
- // Make sure we won't try to allocate the rest parameter. {params_} was |
- // cleared above. |
- has_rest_ = false; |
} |
+ |
+#ifdef DEBUG |
+ needs_migration_ = false; |
+#endif |
+ |
+ is_lazily_parsed_ = !aborted; |
} |
-void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, |
- AstNodeFactory* ast_node_factory) { |
- // Try to resolve unresolved variables for this Scope and migrate those which |
- // cannot be resolved inside. It doesn't make sense to try to resolve them in |
- // the outer Scopes here, because they are incomplete. |
- for (VariableProxy* proxy = |
- FetchFreeVariables(this, !FLAG_lazy_inner_functions); |
- proxy != nullptr; proxy = proxy->next_unresolved()) { |
- DCHECK(!proxy->is_resolved()); |
- VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
- migrate_to->AddUnresolved(copy); |
+void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { |
+ DCHECK(!force_eager_compilation_); |
+ VariableProxy* unresolved = nullptr; |
+ |
+ if (!outer_scope_->is_script_scope()) { |
+ // Try to resolve unresolved variables for this Scope and migrate those |
+ // which cannot be resolved inside. It doesn't make sense to try to resolve |
+ // them in the outer Scopes here, because they are incomplete. |
+ for (VariableProxy* proxy = |
+ FetchFreeVariables(this, !FLAG_lazy_inner_functions); |
+ proxy != nullptr; proxy = proxy->next_unresolved()) { |
+ DCHECK(!proxy->is_resolved()); |
+ VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
+ copy->set_next_unresolved(unresolved); |
+ unresolved = copy; |
+ } |
+ |
+ // Clear arguments_ if unused. This is used as a signal for optimization. |
+ if (arguments_ != nullptr && |
+ !(MustAllocate(arguments_) && !has_arguments_parameter_)) { |
+ arguments_ = nullptr; |
+ } |
} |
- // Push scope data up to migrate_to. Note that migrate_to and this Scope |
- // describe the same Scope, just in different Zones. |
- PropagateUsageFlagsToScope(migrate_to); |
- if (scope_uses_super_property_) migrate_to->scope_uses_super_property_ = true; |
- if (inner_scope_calls_eval_) migrate_to->inner_scope_calls_eval_ = true; |
- if (is_lazily_parsed_) migrate_to->is_lazily_parsed_ = true; |
- DCHECK(!force_eager_compilation_); |
- migrate_to->set_start_position(start_position_); |
- migrate_to->set_end_position(end_position_); |
- migrate_to->set_language_mode(language_mode()); |
- migrate_to->arity_ = arity_; |
- migrate_to->force_context_allocation_ = force_context_allocation_; |
- outer_scope_->RemoveInnerScope(this); |
- DCHECK_EQ(outer_scope_, migrate_to->outer_scope_); |
- DCHECK_EQ(outer_scope_->zone(), migrate_to->zone()); |
- DCHECK_EQ(NeedsHomeObject(), migrate_to->NeedsHomeObject()); |
- DCHECK_EQ(asm_function_, migrate_to->asm_function_); |
+ ResetAfterPreparsing(false); |
+ |
+ unresolved_ = unresolved; |
} |
#ifdef DEBUG |
@@ -1446,6 +1446,7 @@ void Scope::CheckScopePositions() { |
} |
void Scope::CheckZones() { |
+ DCHECK(!needs_migration_); |
for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
CHECK_EQ(scope->zone(), zone()); |
} |
@@ -1631,6 +1632,8 @@ VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, |
stack = proxy; |
} else if (info != nullptr) { |
ResolveTo(info, proxy, var); |
+ } else { |
+ var->set_is_used(); |
} |
} |
@@ -1817,6 +1820,8 @@ void ModuleScope::AllocateModuleVariables() { |
void Scope::AllocateVariablesRecursively() { |
DCHECK(!already_resolved_); |
DCHECK_EQ(0, num_stack_slots_); |
+ // Don't allocate variables of preparsed scopes. |
+ if (is_lazily_parsed_) return; |
// Allocate variables for inner scopes. |
for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |