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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 2646443005: Track async causal stack traces (Closed)
Patch Set: Observatory UI support Created 3 years, 11 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 unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698