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/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 (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { | |
|
rmacnak
2017/01/26 18:05:57
&& FLAG_sane_async_stacks
Cutch
2017/01/31 23:45:31
Done.
| |
| 1135 // We are returning from an asynchronous closure. Before we do that, be | |
| 1136 // sure to clear the thread's asynchronous stack trace. | |
| 1137 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | |
| 1138 ASSERT(!async_lib.IsNull()); | |
| 1139 const String& private_name = String::ZoneHandle( | |
| 1140 async_lib.PrivateName(Symbols::ClearAsyncThreadStackTrace())); | |
| 1141 ASSERT(!private_name.IsNull()); | |
| 1142 const Function& async_clear_thread_stack_trace = Function::ZoneHandle( | |
| 1143 Z, | |
| 1144 Resolver::ResolveStatic(async_lib, String::ZoneHandle(String::null()), | |
|
rmacnak
2017/01/26 18:05:57
It might be worth caching the three helper functio
Cutch
2017/01/31 23:45:31
Done.
| |
| 1145 private_name, 0, Object::null_array())); | |
| 1146 ASSERT(!async_clear_thread_stack_trace.IsNull()); | |
| 1147 // Mark that this function is not debuggable. | |
| 1148 async_clear_thread_stack_trace.set_is_debuggable(false); | |
|
rmacnak
2017/01/26 18:05:57
I thought we can't step into native functions anyw
Cutch
2017/01/31 23:45:30
Acknowledged.
| |
| 1149 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = | |
| 1150 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0); | |
| 1151 StaticCallInstr* call_async_clear_thread_stack_trace = new (Z) | |
| 1152 StaticCallInstr(node->token_pos().ToSynthetic(), | |
| 1153 async_clear_thread_stack_trace, Object::null_array(), | |
| 1154 no_arguments, owner()->ic_data_array()); | |
| 1155 Do(call_async_clear_thread_stack_trace); | |
| 1156 } | |
| 1157 | |
| 1134 // Async functions contain two types of return statements: | 1158 // Async functions contain two types of return statements: |
| 1135 // 1) Returns that should complete the completer once all finally blocks have | 1159 // 1) Returns that should complete the completer once all finally blocks have |
| 1136 // been inlined (call: :async_completer.complete(return_value)). These | 1160 // been inlined (call: :async_completer.complete(return_value)). These |
| 1137 // returns end up returning null in the end. | 1161 // returns end up returning null in the end. |
| 1138 // 2) "Continuation" returns that should not complete the completer but return | 1162 // 2) "Continuation" returns that should not complete the completer but return |
| 1139 // the value. | 1163 // the value. |
| 1140 // | 1164 // |
| 1141 // We distinguish those kinds of nodes via is_regular_return(). | 1165 // We distinguish those kinds of nodes via is_regular_return(). |
| 1142 // | 1166 // |
| 1143 if (function.IsAsyncClosure() && | 1167 if (function.IsAsyncClosure() && |
| (...skipping 2636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3780 // the function. | 3804 // the function. |
| 3781 Value* null_constant = Bind( | 3805 Value* null_constant = Bind( |
| 3782 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 3806 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
| 3783 Do(BuildStoreLocal(*temp_local, null_constant, | 3807 Do(BuildStoreLocal(*temp_local, null_constant, |
| 3784 ST(node->token_pos()))); | 3808 ST(node->token_pos()))); |
| 3785 } | 3809 } |
| 3786 } | 3810 } |
| 3787 } | 3811 } |
| 3788 } | 3812 } |
| 3789 | 3813 |
| 3814 if (is_top_level_sequence && | |
| 3815 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { | |
|
rmacnak
2017/01/26 18:05:57
&& FLAG_sane_async_stacks
Cutch
2017/01/31 23:45:30
Done.
| |
| 3816 LocalScope* top_scope = node->scope(); | |
| 3817 // Fetch the :async_stack_trace variable and store it into the thread. | |
| 3818 LocalVariable* async_stack_trace_var = | |
| 3819 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | |
| 3820 ASSERT((async_stack_trace_var != NULL) && | |
| 3821 async_stack_trace_var->is_captured()); | |
| 3822 // Load :async_stack_trace | |
| 3823 Value* async_stack_trace_value = Bind(BuildLoadLocal( | |
| 3824 *async_stack_trace_var, node->token_pos().ToSynthetic())); | |
| 3825 // Setup arguments for _asyncSetThreadStackTrace. | |
| 3826 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
| 3827 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); | |
| 3828 arguments->Add(PushArgument(async_stack_trace_value)); | |
| 3829 | |
| 3830 // Lookup _asyncSetThreadStackTrace | |
| 3831 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | |
| 3832 ASSERT(!async_lib.IsNull()); | |
| 3833 const String& private_name = String::ZoneHandle( | |
| 3834 async_lib.PrivateName(Symbols::SetAsyncThreadStackTrace())); | |
| 3835 ASSERT(!private_name.IsNull()); | |
| 3836 const Function& async_set_thread_stack_trace = Function::ZoneHandle( | |
| 3837 Z, | |
| 3838 Resolver::ResolveStatic(async_lib, String::ZoneHandle(String::null()), | |
| 3839 private_name, 1, Object::null_array())); | |
|
siva
2017/01/26 19:26:23
Agree with Ryan might be worth caching these funct
Cutch
2017/01/31 23:45:30
Done.
| |
| 3840 ASSERT(!async_set_thread_stack_trace.IsNull()); | |
| 3841 // Mark that this function is not debuggable. | |
| 3842 async_set_thread_stack_trace.set_is_debuggable(false); | |
| 3843 // Call _asyncSetThreadStackTrace | |
| 3844 StaticCallInstr* call_async_set_thread_stack_trace = new (Z) | |
| 3845 StaticCallInstr(node->token_pos().ToSynthetic(), | |
| 3846 async_set_thread_stack_trace, Object::null_array(), | |
| 3847 arguments, owner()->ic_data_array()); | |
| 3848 Do(call_async_set_thread_stack_trace); | |
| 3849 } | |
| 3850 | |
| 3851 | |
| 3790 if (FLAG_support_debugger && is_top_level_sequence && | 3852 if (FLAG_support_debugger && is_top_level_sequence && |
| 3791 function.is_debuggable()) { | 3853 function.is_debuggable()) { |
| 3792 // Place a debug check at method entry to ensure breaking on a method always | 3854 // Place a debug check at method entry to ensure breaking on a method always |
| 3793 // happens, even if there are no assignments/calls/runtimecalls in the first | 3855 // happens, even if there are no assignments/calls/runtimecalls in the first |
| 3794 // basic block. Place this check at the last parameter to ensure parameters | 3856 // basic block. Place this check at the last parameter to ensure parameters |
| 3795 // are in scope in the debugger at method entry. | 3857 // are in scope in the debugger at method entry. |
| 3796 const int num_params = function.NumParameters(); | 3858 const int num_params = function.NumParameters(); |
| 3797 TokenPosition check_pos = TokenPosition::kNoSource; | 3859 TokenPosition check_pos = TokenPosition::kNoSource; |
| 3798 if (num_params > 0) { | 3860 if (num_params > 0) { |
| 3799 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3861 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4333 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); | 4395 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); |
| 4334 ASSERT(found); | 4396 ASSERT(found); |
| 4335 } | 4397 } |
| 4336 | 4398 |
| 4337 | 4399 |
| 4338 void FlowGraphBuilder::Bailout(const char* reason) const { | 4400 void FlowGraphBuilder::Bailout(const char* reason) const { |
| 4339 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4401 parsed_function_.Bailout("FlowGraphBuilder", reason); |
| 4340 } | 4402 } |
| 4341 | 4403 |
| 4342 } // namespace dart | 4404 } // namespace dart |
| OLD | NEW |