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

Unified Diff: runtime/vm/parser.cc

Issue 1308163006: Reduce the number of captured variables in async code, by only capturing local (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 5 years, 3 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/flow_graph_builder.cc ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 731c13fbc007bc438cb47ca52008b64ba03195d6..21ca85bda9b68402545174bc87600ca1e97c5f54 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -3490,7 +3490,7 @@ SequenceNode* Parser::ParseFunc(const Function& func) {
body = CloseSyncGenFunction(generated_body_closure, body);
generated_body_closure.set_end_token_pos(end_token_pos);
} else if (func.IsSyncGenClosure()) {
- body->scope()->RecursivelyCaptureAllVariables();
+ // body is unchanged.
} else if (func.IsAsyncGenerator()) {
body = CloseAsyncGeneratorFunction(generated_body_closure, body);
generated_body_closure.set_end_token_pos(end_token_pos);
@@ -6319,8 +6319,8 @@ SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) {
no_args));
// Suspend after the close.
- AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
- await_marker->set_scope(current_block_->scope);
+ AwaitMarkerNode* await_marker =
+ new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
current_block_->statements->Add(await_marker);
ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
@@ -6609,6 +6609,8 @@ RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
SequenceNode* Parser::CloseSyncGenFunction(const Function& closure,
SequenceNode* closure_body) {
+ // Explicitly reference variables of the sync generator function from the
+ // closure body in order to mark them as captured.
LocalVariable* existing_var =
closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
ASSERT((existing_var != NULL) && existing_var->is_captured());
@@ -6754,11 +6756,9 @@ void Parser::AddContinuationVariables() {
LocalVariable* await_jump_var = new (Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
current_block_->scope->AddVariable(await_jump_var);
- current_block_->scope->CaptureVariable(await_jump_var);
LocalVariable* await_ctx_var = new (Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
current_block_->scope->AddVariable(await_ctx_var);
- current_block_->scope->CaptureVariable(await_ctx_var);
}
@@ -6772,19 +6772,15 @@ void Parser::AddAsyncClosureVariables() {
LocalVariable* async_op_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
current_block_->scope->AddVariable(async_op_var);
- current_block_->scope->CaptureVariable(async_op_var);
LocalVariable* async_then_callback_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
current_block_->scope->AddVariable(async_then_callback_var);
- current_block_->scope->CaptureVariable(async_then_callback_var);
LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
current_block_->scope->AddVariable(async_catch_error_callback_var);
- current_block_->scope->CaptureVariable(async_catch_error_callback_var);
LocalVariable* async_completer = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
current_block_->scope->AddVariable(async_completer);
- current_block_->scope->CaptureVariable(async_completer);
}
@@ -6803,19 +6799,15 @@ void Parser::AddAsyncGeneratorVariables() {
LocalVariable* controller_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
current_block_->scope->AddVariable(controller_var);
- current_block_->scope->CaptureVariable(controller_var);
LocalVariable* async_op_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
current_block_->scope->AddVariable(async_op_var);
- current_block_->scope->CaptureVariable(async_op_var);
LocalVariable* async_then_callback_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
current_block_->scope->AddVariable(async_then_callback_var);
- current_block_->scope->CaptureVariable(async_then_callback_var);
LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
current_block_->scope->AddVariable(async_catch_error_callback_var);
- current_block_->scope->CaptureVariable(async_catch_error_callback_var);
}
@@ -6907,8 +6899,8 @@ SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
ASSERT(!closure_func.IsNull());
ASSERT(closure_body != NULL);
- // Make sure the implicit variables of the async generator function
- // are captured.
+ // Explicitly reference variables of the async genenerator function from the
+ // closure body in order to mark them as captured.
LocalVariable* existing_var = closure_body->scope()->LookupVariable(
Symbols::AwaitJumpVar(), false);
ASSERT((existing_var != NULL) && existing_var->is_captured());
@@ -7046,29 +7038,6 @@ SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
ASSERT(new_body != NULL);
ASSERT(new_body->scope() != NULL);
-
- // Implicitly mark those variables below as captured. We currently mark all
- // variables of all scopes as captured, but as soon as we do something
- // smarter we rely on these internal variables to be available.
- LocalVariable* existing_var = new_body->scope()->LookupVariable(
- Symbols::AwaitJumpVar(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- existing_var = new_body->scope()->LookupVariable(
- Symbols::AwaitContextVar(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- existing_var = new_body->scope()->LookupVariable(
- Symbols::Controller(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- existing_var = new_body->scope()->LookupVariable(
- Symbols::AsyncOperationParam(), false);
- ASSERT(existing_var != NULL);
- existing_var = new_body->scope()->LookupVariable(
- Symbols::AsyncOperationErrorParam(), false);
- ASSERT(existing_var != NULL);
- existing_var = new_body->scope()->LookupVariable(
- Symbols::AsyncOperationStackTraceParam(), false);
- ASSERT(existing_var != NULL);
- new_body->scope()->RecursivelyCaptureAllVariables();
return new_body;
}
@@ -7108,6 +7077,8 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
ASSERT(!closure.IsNull());
ASSERT(closure_body != NULL);
+ // Explicitly reference variables of the async function from the
+ // closure body in order to mark them as captured.
LocalVariable* existing_var =
closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
ASSERT((existing_var != NULL) && existing_var->is_captured());
@@ -7251,22 +7222,10 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) {
// We need a temporary expression to store intermediate return values.
parsed_function()->EnsureExpressionTemp();
- // Implicitly mark those variables below as captured. We currently mark all
- // variables of all scopes as captured (below), but as soon as we do something
- // smarter we rely on these internal variables to be available.
+
SequenceNode* new_body = CloseAsyncTryBlock(body);
ASSERT(new_body != NULL);
ASSERT(new_body->scope() != NULL);
- LocalVariable* existing_var =
- new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- existing_var =
- new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- existing_var =
- new_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
- ASSERT((existing_var != NULL) && existing_var->is_captured());
- new_body->scope()->RecursivelyCaptureAllVariables();
return new_body;
}
@@ -8543,7 +8502,7 @@ static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope,
Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
try_index))));
LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name);
- ASSERT((var != NULL) && var->is_captured());
+ ASSERT(var != NULL);
return var;
}
@@ -8735,14 +8694,15 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
new(Z) LoadLocalNode(stream_pos, iterator_var),
Symbols::MoveNext(),
no_args);
+ OpenBlock();
AstNode* await_moveNext =
new(Z) AwaitNode(stream_pos,
iterator_moveNext,
saved_try_ctx,
async_saved_try_ctx,
outer_saved_try_ctx,
- outer_async_saved_try_ctx);
- OpenBlock();
+ outer_async_saved_try_ctx,
+ current_block_->scope);
AwaitTransformer at(current_block_->statements, async_temp_scope_);
await_moveNext = at.Transform(await_moveNext);
SequenceNode* await_preamble = CloseBlock();
@@ -9574,7 +9534,6 @@ void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) {
Type::ZoneHandle(Z, Type::DynamicType()));
ASSERT(async_temp_scope_ != NULL);
async_temp_scope_->AddVariable(async_saved_try_ctx);
- current_block_->scope->CaptureVariable(async_saved_try_ctx);
ASSERT(saved_try_context != NULL);
current_block_->statements->Add(new(Z) StoreLocalNode(
Scanner::kNoSourcePos,
@@ -9908,8 +9867,8 @@ AstNode* Parser::ParseYieldStatement() {
new(Z) LiteralNode(TokenPos(), Bool::True()));
yield->AddNode(set_is_yield_each);
}
- AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
- await_marker->set_scope(current_block_->scope);
+ AwaitMarkerNode* await_marker =
+ new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
yield->AddNode(await_marker);
// Return true to indicate that a value has been generated.
ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
@@ -9976,8 +9935,8 @@ AstNode* Parser::ParseYieldStatement() {
new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
yield->AddNode(if_is_cancelled);
- AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
- await_marker->set_scope(current_block_->scope);
+ AwaitMarkerNode* await_marker =
+ new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
yield->AddNode(await_marker);
ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
continuation_return->set_return_type(ReturnNode::kContinuationTarget);
@@ -10997,7 +10956,8 @@ AstNode* Parser::ParseUnaryExpr() {
saved_try_ctx,
async_saved_try_ctx,
outer_saved_try_ctx,
- outer_async_saved_try_ctx);
+ outer_async_saved_try_ctx,
+ current_block_->scope);
} else if (IsPrefixOperator(CurrentToken())) {
Token::Kind unary_op = CurrentToken();
if (unary_op == Token::kSUB) {
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698