Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 intptr_t current_context_level = owner()->context_level(); | 1106 intptr_t current_context_level = owner()->context_level(); |
| 1107 ASSERT(current_context_level >= 0); | 1107 ASSERT(current_context_level >= 0); |
| 1108 if (HasContextScope()) { | 1108 if (HasContextScope()) { |
| 1109 UnchainContexts(current_context_level); | 1109 UnchainContexts(current_context_level); |
| 1110 } | 1110 } |
| 1111 | 1111 |
| 1112 AddReturnExit(node->token_pos(), return_value); | 1112 AddReturnExit(node->token_pos(), return_value); |
| 1113 | 1113 |
| 1114 if ((function.IsAsyncClosure() || function.IsSyncGenClosure()) && | 1114 if ((function.IsAsyncClosure() || |
| 1115 function.IsSyncGenClosure() || | |
| 1116 function.IsAsyncGenClosure()) && | |
| 1115 (node->return_type() == ReturnNode::kContinuationTarget)) { | 1117 (node->return_type() == ReturnNode::kContinuationTarget)) { |
| 1116 JoinEntryInstr* const join = new(I) JoinEntryInstr( | 1118 JoinEntryInstr* const join = new(I) JoinEntryInstr( |
| 1117 owner()->AllocateBlockId(), owner()->try_index()); | 1119 owner()->AllocateBlockId(), owner()->try_index()); |
| 1118 owner()->await_joins()->Add(join); | 1120 owner()->await_joins()->Add(join); |
| 1119 exit_ = join; | 1121 exit_ = join; |
| 1120 } | 1122 } |
| 1121 } | 1123 } |
| 1122 | 1124 |
| 1123 | 1125 |
| 1124 // <Expression> ::= Literal { literal: Instance } | 1126 // <Expression> ::= Literal { literal: Instance } |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1476 return new(I) AssertAssignableInstr(token_pos, | 1478 return new(I) AssertAssignableInstr(token_pos, |
| 1477 value, | 1479 value, |
| 1478 instantiator, | 1480 instantiator, |
| 1479 instantiator_type_arguments, | 1481 instantiator_type_arguments, |
| 1480 dst_type, | 1482 dst_type, |
| 1481 dst_name, | 1483 dst_name, |
| 1482 deopt_id); | 1484 deopt_id); |
| 1483 } | 1485 } |
| 1484 | 1486 |
| 1485 | 1487 |
| 1486 void EffectGraphVisitor::BuildYieldJump(LocalVariable* old_context, | 1488 void EffectGraphVisitor::BuildAsyncYieldJump(LocalVariable* old_context, |
| 1487 LocalVariable* iterator_param, | 1489 const intptr_t old_ctx_level, |
|
Ivan Posva
2015/02/23 08:23:36
old_ctx_level is not used in this function. Why is
hausner
2015/02/23 17:12:01
Copy-paste error. I think I will need it though si
| |
| 1488 const intptr_t old_ctx_level, | 1490 JoinEntryInstr* target) { |
| 1489 JoinEntryInstr* target) { | 1491 // Building a jump consists of the following actions: |
| 1492 // * Restore the old context from :await_cxt_var. | |
| 1493 // * Append a Goto to the target's join. | |
| 1494 ASSERT((old_context != NULL) && old_context->is_captured()); | |
| 1495 | |
| 1496 // Restore the saved continuation context, i.e. the context that was | |
| 1497 // saved into :await_ctx_var before the closure suspended. | |
| 1498 BuildRestoreContext(*old_context); | |
| 1499 | |
| 1500 // Goto saved join. | |
| 1501 Goto(target); | |
| 1502 } | |
| 1503 | |
| 1504 | |
| 1505 void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context, | |
| 1506 LocalVariable* iterator_param, | |
| 1507 const intptr_t old_ctx_level, | |
| 1508 JoinEntryInstr* target) { | |
| 1490 // Building a jump consists of the following actions: | 1509 // Building a jump consists of the following actions: |
| 1491 // * Load the generator body's iterator parameter (:iterator) | 1510 // * Load the generator body's iterator parameter (:iterator) |
| 1492 // from the current context into a temporary. | 1511 // from the current context into a temporary. |
| 1493 // * Restore the old context from :await_cxt_var. | 1512 // * Restore the old context from :await_cxt_var. |
| 1494 // * Copy the iterator saved above into the restored context. | 1513 // * Copy the iterator saved above into the restored context. |
| 1495 // * Append a Goto to the target's join. | 1514 // * Append a Goto to the target's join. |
| 1496 ASSERT((iterator_param != NULL) && iterator_param->is_captured()); | 1515 ASSERT((iterator_param != NULL) && iterator_param->is_captured()); |
| 1497 ASSERT((old_context != NULL) && old_context->is_captured()); | 1516 ASSERT((old_context != NULL) && old_context->is_captured()); |
| 1498 // Before restoring the context we need to temporarily save the | 1517 // Before restoring the context we need to temporarily save the |
| 1499 // iterator parameter. | 1518 // iterator parameter. |
| (...skipping 2375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3875 pos++; | 3894 pos++; |
| 3876 } | 3895 } |
| 3877 } | 3896 } |
| 3878 | 3897 |
| 3879 // Continuation part: | 3898 // Continuation part: |
| 3880 // If this node sequence is the body of a function with continuations, | 3899 // If this node sequence is the body of a function with continuations, |
| 3881 // leave room for a preamble. | 3900 // leave room for a preamble. |
| 3882 // The preamble is generated after visiting the body. | 3901 // The preamble is generated after visiting the body. |
| 3883 GotoInstr* preamble_start = NULL; | 3902 GotoInstr* preamble_start = NULL; |
| 3884 if (is_top_level_sequence && | 3903 if (is_top_level_sequence && |
| 3885 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { | 3904 (function.IsAsyncClosure() || |
| 3905 function.IsSyncGenClosure() || | |
| 3906 function.IsAsyncGenClosure())) { | |
| 3886 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( | 3907 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( |
| 3887 owner()->AllocateBlockId(), owner()->try_index()); | 3908 owner()->AllocateBlockId(), owner()->try_index()); |
| 3888 ASSERT(exit() != NULL); | 3909 ASSERT(exit() != NULL); |
| 3889 exit()->Goto(preamble_end); | 3910 exit()->Goto(preamble_end); |
| 3890 ASSERT(exit()->next()->IsGoto()); | 3911 ASSERT(exit()->next()->IsGoto()); |
| 3891 preamble_start = exit()->next()->AsGoto(); | 3912 preamble_start = exit()->next()->AsGoto(); |
| 3892 ASSERT(preamble_start->IsGoto()); | 3913 ASSERT(preamble_start->IsGoto()); |
| 3893 exit_ = preamble_end; | 3914 exit_ = preamble_end; |
| 3894 } | 3915 } |
| 3895 | 3916 |
| 3896 intptr_t i = 0; | 3917 intptr_t i = 0; |
| 3897 while (is_open() && (i < node->length())) { | 3918 while (is_open() && (i < node->length())) { |
| 3898 EffectGraphVisitor for_effect(owner()); | 3919 EffectGraphVisitor for_effect(owner()); |
| 3899 node->NodeAt(i++)->Visit(&for_effect); | 3920 node->NodeAt(i++)->Visit(&for_effect); |
| 3900 Append(for_effect); | 3921 Append(for_effect); |
| 3901 if (!is_open()) { | 3922 if (!is_open()) { |
| 3902 // E.g., because of a JumpNode. | 3923 // E.g., because of a JumpNode. |
| 3903 break; | 3924 break; |
| 3904 } | 3925 } |
| 3905 } | 3926 } |
| 3906 | 3927 |
| 3907 // Continuation part: | 3928 // Continuation part: |
| 3908 // After generating the CFG for the body we can create the preamble | 3929 // After generating the CFG for the body we can create the preamble |
| 3909 // because we know exactly how many continuation states we need. | 3930 // because we know exactly how many continuation states we need. |
| 3910 if (is_top_level_sequence && | 3931 if (is_top_level_sequence && |
| 3911 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { | 3932 (function.IsAsyncClosure() || |
| 3933 function.IsSyncGenClosure() || | |
| 3934 function.IsAsyncGenClosure())) { | |
| 3912 ASSERT(preamble_start != NULL); | 3935 ASSERT(preamble_start != NULL); |
| 3913 // We are at the top level. Fetch the corresponding scope. | 3936 // We are at the top level. Fetch the corresponding scope. |
| 3914 LocalScope* top_scope = node->scope(); | 3937 LocalScope* top_scope = node->scope(); |
| 3915 LocalVariable* jump_var = top_scope->LookupVariable( | 3938 LocalVariable* jump_var = top_scope->LookupVariable( |
| 3916 Symbols::AwaitJumpVar(), false); | 3939 Symbols::AwaitJumpVar(), false); |
| 3917 ASSERT(jump_var != NULL && jump_var->is_captured()); | 3940 ASSERT(jump_var != NULL && jump_var->is_captured()); |
| 3918 Instruction* saved_entry = entry_; | 3941 Instruction* saved_entry = entry_; |
| 3919 Instruction* saved_exit = exit_; | 3942 Instruction* saved_exit = exit_; |
| 3920 entry_ = NULL; | 3943 entry_ = NULL; |
| 3921 exit_ = NULL; | 3944 exit_ = NULL; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 3947 false); | 3970 false); |
| 3948 LocalVariable* stack_trace_param = | 3971 LocalVariable* stack_trace_param = |
| 3949 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(), | 3972 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(), |
| 3950 false); | 3973 false); |
| 3951 for_true.BuildAwaitJump(old_context, | 3974 for_true.BuildAwaitJump(old_context, |
| 3952 result_param, | 3975 result_param, |
| 3953 error_param, | 3976 error_param, |
| 3954 stack_trace_param, | 3977 stack_trace_param, |
| 3955 (*owner()->await_levels())[i], | 3978 (*owner()->await_levels())[i], |
| 3956 (*owner()->await_joins())[i]); | 3979 (*owner()->await_joins())[i]); |
| 3980 } else if (function.IsAsyncGenClosure()) { | |
| 3981 for_true.BuildAsyncYieldJump(old_context, | |
| 3982 (*owner()->await_levels())[i], | |
| 3983 (*owner()->await_joins())[i]); | |
| 3984 | |
| 3957 } else { | 3985 } else { |
| 3958 ASSERT(function.IsSyncGenClosure()); | 3986 ASSERT(function.IsSyncGenClosure()); |
| 3959 LocalVariable* iterator_param = | 3987 LocalVariable* iterator_param = |
| 3960 top_scope->LookupVariable(Symbols::IteratorParameter(), false); | 3988 top_scope->LookupVariable(Symbols::IteratorParameter(), false); |
| 3961 for_true.BuildYieldJump(old_context, | 3989 for_true.BuildSyncYieldJump(old_context, |
| 3962 iterator_param, | 3990 iterator_param, |
| 3963 (*owner()->await_levels())[i], | 3991 (*owner()->await_levels())[i], |
| 3964 (*owner()->await_joins())[i]); | 3992 (*owner()->await_joins())[i]); |
| 3965 } | 3993 } |
| 3966 | 3994 |
| 3967 Join(for_test, for_true, for_false); | 3995 Join(for_test, for_true, for_false); |
| 3968 if (i == 0) { | 3996 if (i == 0) { |
| 3969 // Manually link up the preamble start. | 3997 // Manually link up the preamble start. |
| 3970 preamble_start->previous()->set_next(for_test.entry()); | 3998 preamble_start->previous()->set_next(for_test.entry()); |
| 3971 for_test.entry()->set_previous(preamble_start->previous()); | 3999 for_test.entry()->set_previous(preamble_start->previous()); |
| 3972 } | 4000 } |
| 3973 if (i == (num_await_states - 1)) { | 4001 if (i == (num_await_states - 1)) { |
| 3974 // Link up preamble end. | 4002 // Link up preamble end. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4356 Report::MessageF(Report::kBailout, | 4384 Report::MessageF(Report::kBailout, |
| 4357 Script::Handle(function.script()), | 4385 Script::Handle(function.script()), |
| 4358 function.token_pos(), | 4386 function.token_pos(), |
| 4359 "FlowGraphBuilder Bailout: %s %s", | 4387 "FlowGraphBuilder Bailout: %s %s", |
| 4360 String::Handle(function.name()).ToCString(), | 4388 String::Handle(function.name()).ToCString(), |
| 4361 reason); | 4389 reason); |
| 4362 UNREACHABLE(); | 4390 UNREACHABLE(); |
| 4363 } | 4391 } |
| 4364 | 4392 |
| 4365 } // namespace dart | 4393 } // namespace dart |
| OLD | NEW |