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

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

Issue 2690873005: Enable causal stacktrace in kernel (Closed)
Patch Set: function.set_is_inlinable to make precompiled builds work too Created 3 years, 10 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
« no previous file with comments | « runtime/vm/kernel_reader.cc ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 <map> 5 #include <map>
6 #include <set> 6 #include <set>
7 #include <string> 7 #include <string>
8 8
9 #include "vm/kernel_to_il.h" 9 #include "vm/kernel_to_il.h"
10 10
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 --depth_.catch_; 676 --depth_.catch_;
677 } 677 }
678 678
679 679
680 void ScopeBuilder::VisitFunctionNode(FunctionNode* node) { 680 void ScopeBuilder::VisitFunctionNode(FunctionNode* node) {
681 List<TypeParameter>& type_parameters = node->type_parameters(); 681 List<TypeParameter>& type_parameters = node->type_parameters();
682 for (intptr_t i = 0; i < type_parameters.length(); ++i) { 682 for (intptr_t i = 0; i < type_parameters.length(); ++i) {
683 VisitTypeParameter(type_parameters[i]); 683 VisitTypeParameter(type_parameters[i]);
684 } 684 }
685 685
686 if (FLAG_causal_async_stacks &&
687 (node->dart_async_marker() == FunctionNode::kAsync ||
688 node->dart_async_marker() == FunctionNode::kAsyncStar)) {
689 LocalVariable* asyncStackTraceVar = MakeVariable(
690 TokenPosition::kNoSource, TokenPosition::kNoSource,
691 Symbols::AsyncStackTraceVar(), AbstractType::dynamic_type());
692 scope_->AddVariable(asyncStackTraceVar);
693 }
694
686 if (node->async_marker() == FunctionNode::kSyncYielding) { 695 if (node->async_marker() == FunctionNode::kSyncYielding) {
687 LocalScope* scope = parsed_function_->node_sequence()->scope(); 696 LocalScope* scope = parsed_function_->node_sequence()->scope();
688 intptr_t offset = parsed_function_->function().num_fixed_parameters(); 697 intptr_t offset = parsed_function_->function().num_fixed_parameters();
689 for (intptr_t i = 0; 698 for (intptr_t i = 0;
690 i < parsed_function_->function().NumOptionalPositionalParameters(); 699 i < parsed_function_->function().NumOptionalPositionalParameters();
691 i++) { 700 i++) {
692 scope->VariableAt(offset + i)->set_is_forced_stack(); 701 scope->VariableAt(offset + i)->set_is_forced_stack();
693 } 702 }
694 } 703 }
695 704
696 // Do not visit the positional and named parameters, because they've 705 // Do not visit the positional and named parameters, because they've
697 // already been added to the scope. 706 // already been added to the scope.
698 if (node->body() != NULL) { 707 if (node->body() != NULL) {
699 node->body()->AcceptStatementVisitor(this); 708 node->body()->AcceptStatementVisitor(this);
700 } 709 }
701 710
702 // Ensure that :await_jump_var, :await_ctx_var and :async_op are captured. 711 // Ensure that :await_jump_var, :await_ctx_var, :async_op and
712 // :async_stack_trace are captured.
703 if (node->async_marker() == FunctionNode::kSyncYielding) { 713 if (node->async_marker() == FunctionNode::kSyncYielding) {
704 { 714 {
705 LocalVariable* temp = NULL; 715 LocalVariable* temp = NULL;
706 LookupCapturedVariableByName( 716 LookupCapturedVariableByName(
707 (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp, 717 (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp,
708 Symbols::AwaitJumpVar()); 718 Symbols::AwaitJumpVar());
709 } 719 }
710 { 720 {
711 LocalVariable* temp = NULL; 721 LocalVariable* temp = NULL;
712 LookupCapturedVariableByName( 722 LookupCapturedVariableByName(
713 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp, 723 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp,
714 Symbols::AwaitContextVar()); 724 Symbols::AwaitContextVar());
715 } 725 }
716 { 726 {
717 LocalVariable* temp = 727 LocalVariable* temp =
718 scope_->LookupVariable(Symbols::AsyncOperation(), true); 728 scope_->LookupVariable(Symbols::AsyncOperation(), true);
719 if (temp != NULL) { 729 if (temp != NULL) {
720 scope_->CaptureVariable(temp); 730 scope_->CaptureVariable(temp);
721 } 731 }
722 } 732 }
733 if (FLAG_causal_async_stacks) {
734 LocalVariable* temp =
735 scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true);
736 if (temp != NULL) {
737 scope_->CaptureVariable(temp);
738 }
739 }
723 } 740 }
724 } 741 }
725 742
726 743
727 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) { 744 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) {
728 ASSERT(node->is_native()); 745 ASSERT(node->is_native());
729 if (depth_.function_ == 0) { 746 if (depth_.function_ == 0) {
730 AddSwitchVariable(); 747 AddSwitchVariable();
731 // Promote all currently visible local variables into the context. 748 // Promote all currently visible local variables into the context.
732 // TODO(27590) CaptureLocalVariables promotes to many variables into 749 // TODO(27590) CaptureLocalVariables promotes to many variables into
(...skipping 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 Value* value = Pop(); 2566 Value* value = Pop();
2550 ASSERT(stack_ == NULL); 2567 ASSERT(stack_ == NULL);
2551 2568
2552 const Function& function = parsed_function_->function(); 2569 const Function& function = parsed_function_->function();
2553 if (FLAG_support_debugger && position.IsDebugPause() && 2570 if (FLAG_support_debugger && position.IsDebugPause() &&
2554 !function.is_native()) { 2571 !function.is_native()) {
2555 instructions <<= 2572 instructions <<=
2556 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); 2573 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall);
2557 } 2574 }
2558 2575
2576 if (FLAG_causal_async_stacks &&
2577 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
2578 // We are returning from an asynchronous closure. Before we do that, be
2579 // sure to clear the thread's asynchronous stack trace.
2580 const Function& target = Function::ZoneHandle(
2581 Z, I->object_store()->async_clear_thread_stack_trace());
2582 ASSERT(!target.IsNull());
2583 instructions += StaticCall(TokenPosition::kNoSource, target, 0);
2584 instructions += Drop();
2585 }
2586
2559 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); 2587 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value);
2560 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); 2588 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr);
2561 2589
2562 instructions <<= return_instr; 2590 instructions <<= return_instr;
2563 2591
2564 return instructions.closed(); 2592 return instructions.closed();
2565 } 2593 }
2566 2594
2567 2595
2568 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, 2596 Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 body += Drop(); 3177 body += Drop();
3150 } 3178 }
3151 for (intptr_t i = 0; i < named.length(); i++) { 3179 for (intptr_t i = 0; i < named.length(); i++) {
3152 VariableDeclaration* variable = named[i]; 3180 VariableDeclaration* variable = named[i];
3153 body += LoadLocal(LookupVariable(variable)); 3181 body += LoadLocal(LookupVariable(variable));
3154 body += CheckVariableTypeInCheckedMode(variable); 3182 body += CheckVariableTypeInCheckedMode(variable);
3155 body += Drop(); 3183 body += Drop();
3156 } 3184 }
3157 } 3185 }
3158 3186
3187 if (FLAG_causal_async_stacks &&
3188 (dart_function.IsAsyncFunction() || dart_function.IsAsyncGenerator())) {
3189 LocalScope* scope = parsed_function_->node_sequence()->scope();
3190 // :async_stack_trace = _asyncStackTraceHelper();
3191 const dart::Library& async_lib =
3192 dart::Library::Handle(dart::Library::AsyncLibrary());
3193 const Function& target = Function::ZoneHandle(
3194 Z,
3195 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
3196 ASSERT(!target.IsNull());
3197
3198 body += StaticCall(TokenPosition::kNoSource, target, 0);
3199 LocalVariable* async_stack_trace_var =
3200 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3201 ASSERT(async_stack_trace_var != NULL);
3202 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var);
3203 body += Drop();
3204 }
3205
3159 if (dart_function.is_native()) { 3206 if (dart_function.is_native()) {
3160 body += NativeFunctionBody(function, dart_function); 3207 body += NativeFunctionBody(function, dart_function);
3161 } else if (function->body() != NULL) { 3208 } else if (function->body() != NULL) {
3162 body += TranslateStatement(function->body()); 3209 body += TranslateStatement(function->body());
3163 } 3210 }
3164 if (body.is_open()) { 3211 if (body.is_open()) {
3165 body += NullConstant(); 3212 body += NullConstant();
3166 body += Return(dart_function.end_token_pos()); 3213 body += Return(dart_function.end_token_pos());
3167 } 3214 }
3168 3215
3169 // If functions body contains any yield points build switch statement that 3216 // If functions body contains any yield points build switch statement that
3170 // selects a continuation point based on the value of :await_jump_var. 3217 // selects a continuation point based on the value of :await_jump_var.
3171 if (!yield_continuations_.is_empty()) { 3218 if (!yield_continuations_.is_empty()) {
3172 // The code we are building will be executed right after we enter 3219 // The code we are building will be executed right after we enter
3173 // the function and before any nested contexts are allocated. 3220 // the function and before any nested contexts are allocated.
3174 // Reset current context_depth_ to match this. 3221 // Reset current context_depth_ to match this.
3175 intptr_t current_context_depth = context_depth_; 3222 const intptr_t current_context_depth = context_depth_;
3176 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); 3223 context_depth_ = scopes_->yield_jump_variable->owner()->context_level();
3177 3224
3178 // Prepend an entry corresponding to normal entry to the function. 3225 // Prepend an entry corresponding to normal entry to the function.
3179 yield_continuations_.InsertAt( 3226 yield_continuations_.InsertAt(
3180 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), 3227 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL),
3181 CatchClauseNode::kInvalidTryIndex)); 3228 CatchClauseNode::kInvalidTryIndex));
3182 yield_continuations_[0].entry->LinkTo(body.entry); 3229 yield_continuations_[0].entry->LinkTo(body.entry);
3183 3230
3184 // Build a switch statement. 3231 // Build a switch statement.
3185 Fragment dispatch; 3232 Fragment dispatch;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 3278
3232 // False branch will contain the next comparison. 3279 // False branch will contain the next comparison.
3233 dispatch = Fragment(dispatch.entry, otherwise); 3280 dispatch = Fragment(dispatch.entry, otherwise);
3234 block = otherwise; 3281 block = otherwise;
3235 } 3282 }
3236 body = dispatch; 3283 body = dispatch;
3237 3284
3238 context_depth_ = current_context_depth; 3285 context_depth_ = current_context_depth;
3239 } 3286 }
3240 3287
3288 if (FLAG_causal_async_stacks &&
3289 (dart_function.IsAsyncClosure() || dart_function.IsAsyncGenClosure())) {
3290 // The code we are building will be executed right after we enter
3291 // the function and before any nested contexts are allocated.
3292 // Reset current context_depth_ to match this.
3293 const intptr_t current_context_depth = context_depth_;
3294 context_depth_ = scopes_->yield_jump_variable->owner()->context_level();
3295
3296 Fragment instructions;
3297 LocalScope* scope = parsed_function_->node_sequence()->scope();
3298
3299 const Function& target = Function::ZoneHandle(
3300 Z, I->object_store()->async_set_thread_stack_trace());
3301 ASSERT(!target.IsNull());
3302
3303 // Fetch and load :async_stack_trace
3304 LocalVariable* async_stack_trace_var =
3305 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3306 ASSERT((async_stack_trace_var != NULL) &&
3307 async_stack_trace_var->is_captured());
3308 instructions += LoadLocal(async_stack_trace_var);
3309 instructions += PushArgument();
3310
3311 // Call _asyncSetThreadStackTrace
3312 instructions += StaticCall(TokenPosition::kNoSource, target, 1);
3313 instructions += Drop();
3314
3315 body = instructions + body;
3316 context_depth_ = current_context_depth;
3317 }
3318
3241 if (FLAG_support_debugger && function->position().IsDebugPause() && 3319 if (FLAG_support_debugger && function->position().IsDebugPause() &&
3242 !dart_function.is_native() && dart_function.is_debuggable()) { 3320 !dart_function.is_native() && dart_function.is_debuggable()) {
3243 // If a switch was added above: Start the switch by injecting a debugable 3321 // If a switch was added above: Start the switch by injecting a debugable
3244 // safepoint so stepping over an await works. 3322 // safepoint so stepping over an await works.
3245 // If not, still start the body with a debugable safepoint to ensure 3323 // If not, still start the body with a debugable safepoint to ensure
3246 // breaking on a method always happens, even if there are no 3324 // breaking on a method always happens, even if there are no
3247 // assignments/calls/runtimecalls in the first basic block. 3325 // assignments/calls/runtimecalls in the first basic block.
3248 // Place this check at the last parameter to ensure parameters 3326 // Place this check at the last parameter to ensure parameters
3249 // are in scope in the debugger at method entry. 3327 // are in scope in the debugger at method entry.
3250 const int num_params = dart_function.NumParameters(); 3328 const int num_params = dart_function.NumParameters();
(...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after
6133 *name, parsed_function_->function(), position); 6211 *name, parsed_function_->function(), position);
6134 6212
6135 function.set_is_debuggable(node->dart_async_marker() == 6213 function.set_is_debuggable(node->dart_async_marker() ==
6136 FunctionNode::kSync); 6214 FunctionNode::kSync);
6137 switch (node->dart_async_marker()) { 6215 switch (node->dart_async_marker()) {
6138 case FunctionNode::kSyncStar: 6216 case FunctionNode::kSyncStar:
6139 function.set_modifier(RawFunction::kSyncGen); 6217 function.set_modifier(RawFunction::kSyncGen);
6140 break; 6218 break;
6141 case FunctionNode::kAsync: 6219 case FunctionNode::kAsync:
6142 function.set_modifier(RawFunction::kAsync); 6220 function.set_modifier(RawFunction::kAsync);
6221 function.set_is_inlinable(!FLAG_causal_async_stacks);
6143 break; 6222 break;
6144 case FunctionNode::kAsyncStar: 6223 case FunctionNode::kAsyncStar:
6145 function.set_modifier(RawFunction::kAsyncGen); 6224 function.set_modifier(RawFunction::kAsyncGen);
6225 function.set_is_inlinable(!FLAG_causal_async_stacks);
6146 break; 6226 break;
6147 default: 6227 default:
6148 // no special modifier 6228 // no special modifier
6149 break; 6229 break;
6150 } 6230 }
6151 function.set_is_generated_body(node->async_marker() == 6231 function.set_is_generated_body(node->async_marker() ==
6152 FunctionNode::kSyncYielding); 6232 FunctionNode::kSyncYielding);
6233 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
6234 function.set_is_inlinable(!FLAG_causal_async_stacks);
6235 }
6153 6236
6154 function.set_end_token_pos(node->end_position()); 6237 function.set_end_token_pos(node->end_position());
6155 LocalScope* scope = scopes_->function_scopes[i].scope; 6238 LocalScope* scope = scopes_->function_scopes[i].scope;
6156 const ContextScope& context_scope = 6239 const ContextScope& context_scope =
6157 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_)); 6240 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_));
6158 function.set_context_scope(context_scope); 6241 function.set_context_scope(context_scope);
6159 function.set_kernel_function(node); 6242 function.set_kernel_function(node);
6160 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z), 6243 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z),
6161 function, node, 6244 function, node,
6162 false, // is_method 6245 false, // is_method
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
6299 thread->clear_sticky_error(); 6382 thread->clear_sticky_error();
6300 return error.raw(); 6383 return error.raw();
6301 } 6384 }
6302 } 6385 }
6303 6386
6304 6387
6305 } // namespace kernel 6388 } // namespace kernel
6306 } // namespace dart 6389 } // namespace dart
6307 6390
6308 #endif // !defined(DART_PRECOMPILED_RUNTIME) 6391 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_reader.cc ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698