Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1898)

Unified Diff: runtime/vm/scopes.cc

Issue 1317213003: Improve async code in VM by not unnecessarily capturing parameters of async and (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Avoid duplicate aliases Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/scopes.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/scopes.cc
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index e11fc166824a221e77870d896328f312cb0eb0ab..637e9b72bfa92fa9e1a9a19be20e4290c0722e7c 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -404,18 +404,10 @@ LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) {
LocalScope* current_scope = this;
while (current_scope != NULL) {
LocalVariable* var = current_scope->LocalLookupVariable(name);
- if ((var != NULL) && !var->is_invisible_) {
- if (!test_only) {
- if (var->owner()->function_level() != function_level()) {
- var->set_is_captured();
- }
- // Insert aliases of the variable in intermediate scopes.
- LocalScope* intermediate_scope = this;
- while (intermediate_scope != current_scope) {
- intermediate_scope->variables_.Add(var);
- ASSERT(var->owner() != intermediate_scope); // Item is an alias.
- intermediate_scope = intermediate_scope->parent();
- }
+ // If testing only, return the variable even if invisible.
+ if ((var != NULL) && (!var->is_invisible_ || test_only)) {
+ if (!test_only && (var->owner()->function_level() != function_level())) {
+ CaptureVariable(var);
}
return var;
}
@@ -425,32 +417,29 @@ LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) {
}
-bool LocalScope::CaptureVariable(const String& name) {
- ASSERT(name.IsSymbol());
- LocalScope* current_scope = this;
- while (current_scope != NULL) {
- LocalVariable* var = current_scope->LocalLookupVariable(name);
- if (var != NULL) {
- var->set_is_captured();
- LocalScope* scope = this;
- while (var->owner()->function_level() != scope->function_level()) {
- // Insert an alias of the variable in the top scope of each function
- // level so that the variable is found in the context.
- LocalScope* parent_scope = scope->parent();
- while ((parent_scope != NULL) &&
- (parent_scope->function_level() == scope->function_level())) {
- scope = parent_scope;
- parent_scope = scope->parent();
- }
- scope->variables_.Add(var);
- ASSERT(var->owner() != scope); // Item is an alias.
- scope = parent_scope;
- }
- return true;
+void LocalScope::CaptureVariable(LocalVariable* variable) {
+ ASSERT(variable != NULL);
+ // The variable must exist in an enclosing scope, not necessarily in this one.
+ variable->set_is_captured();
+ const int variable_function_level = variable->owner()->function_level();
+ LocalScope* scope = this;
+ while (scope->function_level() != variable_function_level) {
+ // Insert an alias of the variable in the top scope of each function
+ // level so that the variable is found in the context.
+ LocalScope* parent_scope = scope->parent();
+ while ((parent_scope != NULL) &&
+ (parent_scope->function_level() == scope->function_level())) {
+ scope = parent_scope;
+ parent_scope = scope->parent();
}
- current_scope = current_scope->parent();
+ // An alias may already have been added in this scope, and in that case,
+ // in parent scopes as needed. If so, we are done.
+ if (!scope->AddVariable(variable)) {
+ return;
+ }
+ ASSERT(variable->owner() != scope); // Item is an alias.
+ scope = parent_scope;
}
- return false;
}
@@ -525,9 +514,10 @@ SourceLabel* LocalScope::CheckUnresolvedLabels() {
int LocalScope::NumCapturedVariables() const {
// It is not necessary to traverse parent scopes, since we are only interested
- // in the captured variables referenced in this scope. If this scope
- // references a captured variable declared in a parent scope, it will contain
- // an alias for that variable.
+ // in the captured variables referenced in this scope. If this scope is the
+ // top scope at function level 1 and it (or its children scopes) references a
+ // captured variable declared in a parent scope at function level 0, it will
+ // contain an alias for that variable.
// Since code generation for nested functions is postponed until first
// invocation, the function level of the closure scope can only be 1.
@@ -628,7 +618,6 @@ LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) {
void LocalScope::RecursivelyCaptureAllVariables() {
- bool found = false;
for (intptr_t i = 0; i < num_variables(); i++) {
if ((VariableAt(i)->name().raw() == Symbols::StackTraceVar().raw()) ||
(VariableAt(i)->name().raw() == Symbols::ExceptionVar().raw()) ||
@@ -637,8 +626,7 @@ void LocalScope::RecursivelyCaptureAllVariables() {
// stack.
continue;
}
- found = CaptureVariable(VariableAt(i)->name());
- ASSERT(found);
+ CaptureVariable(VariableAt(i));
}
if (sibling() != NULL) { sibling()->RecursivelyCaptureAllVariables(); }
if (child() != NULL) { child()->RecursivelyCaptureAllVariables(); }
« no previous file with comments | « runtime/vm/scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698