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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 // However, factories may create an instance of the wrong type. | 1124 // However, factories may create an instance of the wrong type. |
1125 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { | 1125 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { |
1126 const AbstractType& dst_type = | 1126 const AbstractType& dst_type = |
1127 AbstractType::ZoneHandle(Z, function.result_type()); | 1127 AbstractType::ZoneHandle(Z, function.result_type()); |
1128 return_value = | 1128 return_value = |
1129 BuildAssignableValue(node->value()->token_pos(), return_value, | 1129 BuildAssignableValue(node->value()->token_pos(), return_value, |
1130 dst_type, Symbols::FunctionResult()); | 1130 dst_type, Symbols::FunctionResult()); |
1131 } | 1131 } |
1132 } | 1132 } |
1133 | 1133 |
| 1134 if (FLAG_causal_async_stacks && |
| 1135 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { |
| 1136 // We are returning from an asynchronous closure. Before we do that, be |
| 1137 // sure to clear the thread's asynchronous stack trace. |
| 1138 const Function& async_clear_thread_stack_trace = Function::ZoneHandle( |
| 1139 Z, isolate()->object_store()->async_clear_thread_stack_trace()); |
| 1140 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = |
| 1141 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
| 1142 StaticCallInstr* call_async_clear_thread_stack_trace = new (Z) |
| 1143 StaticCallInstr(node->token_pos().ToSynthetic(), |
| 1144 async_clear_thread_stack_trace, Object::null_array(), |
| 1145 no_arguments, owner()->ic_data_array()); |
| 1146 Do(call_async_clear_thread_stack_trace); |
| 1147 } |
| 1148 |
1134 // Async functions contain two types of return statements: | 1149 // Async functions contain two types of return statements: |
1135 // 1) Returns that should complete the completer once all finally blocks have | 1150 // 1) Returns that should complete the completer once all finally blocks have |
1136 // been inlined (call: :async_completer.complete(return_value)). These | 1151 // been inlined (call: :async_completer.complete(return_value)). These |
1137 // returns end up returning null in the end. | 1152 // returns end up returning null in the end. |
1138 // 2) "Continuation" returns that should not complete the completer but return | 1153 // 2) "Continuation" returns that should not complete the completer but return |
1139 // the value. | 1154 // the value. |
1140 // | 1155 // |
1141 // We distinguish those kinds of nodes via is_regular_return(). | 1156 // We distinguish those kinds of nodes via is_regular_return(). |
1142 // | 1157 // |
1143 if (function.IsAsyncClosure() && | 1158 if (function.IsAsyncClosure() && |
(...skipping 2641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3785 // the function. | 3800 // the function. |
3786 Value* null_constant = Bind( | 3801 Value* null_constant = Bind( |
3787 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 3802 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
3788 Do(BuildStoreLocal(*temp_local, null_constant, | 3803 Do(BuildStoreLocal(*temp_local, null_constant, |
3789 ST(node->token_pos()))); | 3804 ST(node->token_pos()))); |
3790 } | 3805 } |
3791 } | 3806 } |
3792 } | 3807 } |
3793 } | 3808 } |
3794 | 3809 |
| 3810 if (FLAG_causal_async_stacks && is_top_level_sequence && |
| 3811 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { |
| 3812 LocalScope* top_scope = node->scope(); |
| 3813 // Fetch the :async_stack_trace variable and store it into the thread. |
| 3814 LocalVariable* async_stack_trace_var = |
| 3815 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
| 3816 ASSERT((async_stack_trace_var != NULL) && |
| 3817 async_stack_trace_var->is_captured()); |
| 3818 // Load :async_stack_trace |
| 3819 Value* async_stack_trace_value = Bind(BuildLoadLocal( |
| 3820 *async_stack_trace_var, node->token_pos().ToSynthetic())); |
| 3821 // Setup arguments for _asyncSetThreadStackTrace. |
| 3822 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3823 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 3824 arguments->Add(PushArgument(async_stack_trace_value)); |
| 3825 |
| 3826 const Function& async_set_thread_stack_trace = Function::ZoneHandle( |
| 3827 Z, isolate()->object_store()->async_set_thread_stack_trace()); |
| 3828 ASSERT(!async_set_thread_stack_trace.IsNull()); |
| 3829 // Call _asyncSetThreadStackTrace |
| 3830 StaticCallInstr* call_async_set_thread_stack_trace = new (Z) |
| 3831 StaticCallInstr(node->token_pos().ToSynthetic(), |
| 3832 async_set_thread_stack_trace, Object::null_array(), |
| 3833 arguments, owner()->ic_data_array()); |
| 3834 Do(call_async_set_thread_stack_trace); |
| 3835 } |
| 3836 |
| 3837 |
3795 if (FLAG_support_debugger && is_top_level_sequence && | 3838 if (FLAG_support_debugger && is_top_level_sequence && |
3796 function.is_debuggable()) { | 3839 function.is_debuggable()) { |
3797 // Place a debug check at method entry to ensure breaking on a method always | 3840 // Place a debug check at method entry to ensure breaking on a method always |
3798 // happens, even if there are no assignments/calls/runtimecalls in the first | 3841 // happens, even if there are no assignments/calls/runtimecalls in the first |
3799 // basic block. Place this check at the last parameter to ensure parameters | 3842 // basic block. Place this check at the last parameter to ensure parameters |
3800 // are in scope in the debugger at method entry. | 3843 // are in scope in the debugger at method entry. |
3801 const int num_params = function.NumParameters(); | 3844 const int num_params = function.NumParameters(); |
3802 TokenPosition check_pos = TokenPosition::kNoSource; | 3845 TokenPosition check_pos = TokenPosition::kNoSource; |
3803 if (num_params > 0) { | 3846 if (num_params > 0) { |
3804 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3847 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4341 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); | 4384 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); |
4342 ASSERT(found); | 4385 ASSERT(found); |
4343 } | 4386 } |
4344 | 4387 |
4345 | 4388 |
4346 void FlowGraphBuilder::Bailout(const char* reason) const { | 4389 void FlowGraphBuilder::Bailout(const char* reason) const { |
4347 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4390 parsed_function_.Bailout("FlowGraphBuilder", reason); |
4348 } | 4391 } |
4349 | 4392 |
4350 } // namespace dart | 4393 } // namespace dart |
OLD | NEW |