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

Unified Diff: runtime/vm/ast_transformer.cc

Issue 1274133002: Don't zone-register async callbacks for every await call in the VM. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: load async-op var. 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/lib/core_patch.dart ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/ast_transformer.cc
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index ac3f9f1b9132178de3c66fbec754f6bed1718397..11cb61cabb661db8f66a1726ff8b1e2bf130c74a 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -112,13 +112,9 @@ void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
// Await transformation:
//
// :await_temp_var_X = <expr>;
- // :result_param = :await_temp_var_X;
- // if (:result_param is !Future) {
- // :result_param = Future.value(:result_param);
- // }
// AwaitMarker(kNewContinuationState);
- // :result_param = :result_param.then(:async_op);
- // _asyncCatchHelper(:result_param.catchError, :async_op);
+ // :result_param = _awaitHelper(
+ // :await_temp_var_X, :async_then_callback, :async_catch_error_callback);
// return; // (return_type() == kContinuationTarget)
//
// :saved_try_ctx_var = :await_saved_try_ctx_var_y;
@@ -126,6 +122,10 @@ void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
LocalVariable* async_op = GetVariableInScope(
preamble_->scope(), Symbols::AsyncOperation());
+ LocalVariable* async_then_callback = GetVariableInScope(
+ preamble_->scope(), Symbols::AsyncThenCallback());
+ LocalVariable* async_catch_error_callback = GetVariableInScope(
+ preamble_->scope(), Symbols::AsyncCatchErrorCallback());
LocalVariable* result_param = GetVariableInScope(
preamble_->scope(), Symbols::AsyncOperationParam());
LocalVariable* error_param = GetVariableInScope(
@@ -134,78 +134,34 @@ void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
preamble_->scope(), Symbols::AsyncOperationStackTraceParam());
AstNode* transformed_expr = Transform(node->expr());
- preamble_->Add(new(Z) StoreLocalNode(
- Scanner::kNoSourcePos, result_param, transformed_expr));
-
- LoadLocalNode* load_result_param = new(Z) LoadLocalNode(
- Scanner::kNoSourcePos, result_param);
-
- const Class& future_cls =
- Class::ZoneHandle(Z, thread()->isolate()->object_store()->future_class());
- ASSERT(!future_cls.IsNull());
- const AbstractType& future_type =
- AbstractType::ZoneHandle(Z, future_cls.RareType());
- ASSERT(!future_type.IsNull());
-
- LocalScope* is_not_future_scope = ChainNewScope(preamble_->scope());
- SequenceNode* is_not_future_branch =
- new (Z) SequenceNode(Scanner::kNoSourcePos, is_not_future_scope);
-
- // if (:result_param is !Future) {
- // :result_param = Future.value(:result_param);
- // }
- const Function& value_ctor = Function::ZoneHandle(
- Z, future_cls.LookupFunction(Symbols::FutureValue()));
- ASSERT(!value_ctor.IsNull());
- ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos);
- ctor_args->Add(new (Z) LoadLocalNode(Scanner::kNoSourcePos, result_param));
- ConstructorCallNode* ctor_call =
- new (Z) ConstructorCallNode(Scanner::kNoSourcePos,
- TypeArguments::ZoneHandle(Z),
- value_ctor,
- ctor_args);
- is_not_future_branch->Add(new (Z) StoreLocalNode(
- Scanner::kNoSourcePos, result_param, ctor_call));
- AstNode* is_not_future_test = new (Z) ComparisonNode(
- Scanner::kNoSourcePos,
- Token::kISNOT,
- load_result_param,
- new (Z) TypeNode(Scanner::kNoSourcePos, future_type));
- preamble_->Add(new(Z) IfNode(Scanner::kNoSourcePos,
- is_not_future_test,
- is_not_future_branch,
- NULL));
+ LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr);
AwaitMarkerNode* await_marker = new (Z) AwaitMarkerNode();
await_marker->set_scope(preamble_->scope());
preamble_->Add(await_marker);
- ArgumentListNode* args = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
- args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_op));
- preamble_->Add(new (Z) StoreLocalNode(
- Scanner::kNoSourcePos,
- result_param,
- new(Z) InstanceCallNode(node->token_pos(),
- load_result_param,
- Symbols::FutureThen(),
- args)));
- const Library& core_lib = Library::Handle(Library::CoreLibrary());
- const Function& async_catch_helper = Function::ZoneHandle(
- Z, core_lib.LookupFunctionAllowPrivate(Symbols::AsyncCatchHelper()));
- ASSERT(!async_catch_helper.IsNull());
- ArgumentListNode* catch_helper_args = new (Z) ArgumentListNode(
+ // :result_param = _awaitHelper(
+ // :await_temp, :async_then_callback, :async_catch_error_callback)
+ const Library& async_lib = Library::Handle(Library::AsyncLibrary());
+ const Function& async_await_helper = Function::ZoneHandle(
+ Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper()));
+ ASSERT(!async_await_helper.IsNull());
+ ArgumentListNode* async_await_helper_args = new (Z) ArgumentListNode(
Scanner::kNoSourcePos);
- InstanceGetterNode* catch_error_getter = new (Z) InstanceGetterNode(
- Scanner::kNoSourcePos,
- load_result_param,
- Symbols::FutureCatchError());
- catch_helper_args->Add(catch_error_getter);
- catch_helper_args->Add(new (Z) LoadLocalNode(
- Scanner::kNoSourcePos, async_op));
- preamble_->Add(new (Z) StaticCallNode(
- Scanner::kNoSourcePos,
- async_catch_helper,
- catch_helper_args));
+ async_await_helper_args->Add(
+ new(Z) LoadLocalNode(Scanner::kNoSourcePos, await_temp));
+ async_await_helper_args->Add(
+ new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_then_callback));
+ async_await_helper_args->Add(
+ new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_catch_error_callback));
+ StaticCallNode* await_helper_call = new (Z) StaticCallNode(
+ node->token_pos(),
+ async_await_helper,
+ async_await_helper_args);
+
+ preamble_->Add(new(Z) StoreLocalNode(
+ Scanner::kNoSourcePos, result_param, await_helper_call));
+
ReturnNode* continuation_return = new(Z) ReturnNode(Scanner::kNoSourcePos);
continuation_return->set_return_type(ReturnNode::kContinuationTarget);
preamble_->Add(continuation_return);
@@ -230,6 +186,12 @@ void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
ASSERT(node->outer_saved_try_ctx() == NULL);
}
+ // Load the async_op variable. It is unused, but the observatory uses it
+ // to determine if a breakpoint is inside an asynchronous function.
+ LoadLocalNode* load_async_op = new (Z) LoadLocalNode(
+ Scanner::kNoSourcePos, async_op);
+ preamble_->Add(load_async_op);
+
LoadLocalNode* load_error_param = new (Z) LoadLocalNode(
Scanner::kNoSourcePos, error_param);
LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode(
« no previous file with comments | « runtime/lib/core_patch.dart ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698