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

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

Issue 2690873005: Enable causal stacktrace in kernel (Closed)
Patch Set: Addressed comments 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 | « pkg/kernel/lib/transformations/continuation.dart ('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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp, 713 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp,
714 Symbols::AwaitContextVar()); 714 Symbols::AwaitContextVar());
715 } 715 }
716 { 716 {
717 LocalVariable* temp = 717 LocalVariable* temp =
718 scope_->LookupVariable(Symbols::AsyncOperation(), true); 718 scope_->LookupVariable(Symbols::AsyncOperation(), true);
719 if (temp != NULL) { 719 if (temp != NULL) {
720 scope_->CaptureVariable(temp); 720 scope_->CaptureVariable(temp);
721 } 721 }
722 } 722 }
723 if (FLAG_causal_async_stacks) {
724 LocalVariable* temp =
725 scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true);
726 if (temp != NULL) {
727 scope_->CaptureVariable(temp);
728 }
729 }
723 } 730 }
724 } 731 }
725 732
726 733
727 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) { 734 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) {
728 ASSERT(node->is_native()); 735 ASSERT(node->is_native());
729 if (depth_.function_ == 0) { 736 if (depth_.function_ == 0) {
730 AddSwitchVariable(); 737 AddSwitchVariable();
731 // Promote all currently visible local variables into the context. 738 // Promote all currently visible local variables into the context.
732 // TODO(27590) CaptureLocalVariables promotes to many variables into 739 // TODO(27590) CaptureLocalVariables promotes to many variables into
(...skipping 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 Value* value = Pop(); 2556 Value* value = Pop();
2550 ASSERT(stack_ == NULL); 2557 ASSERT(stack_ == NULL);
2551 2558
2552 const Function& function = parsed_function_->function(); 2559 const Function& function = parsed_function_->function();
2553 if (FLAG_support_debugger && position.IsDebugPause() && 2560 if (FLAG_support_debugger && position.IsDebugPause() &&
2554 !function.is_native()) { 2561 !function.is_native()) {
2555 instructions <<= 2562 instructions <<=
2556 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); 2563 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall);
2557 } 2564 }
2558 2565
2566 if (FLAG_causal_async_stacks &&
2567 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
2568 // We are returning from an asynchronous closure. Before we do that, be
2569 // sure to clear the thread's asynchronous stack trace.
2570 const Function& target = Function::ZoneHandle(
2571 Z, I->object_store()->async_clear_thread_stack_trace());
2572 ASSERT(!target.IsNull());
2573 instructions += StaticCall(TokenPosition::kNoSource, target, 0);
2574 instructions += Drop();
2575 }
2576
2559 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); 2577 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value);
2560 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); 2578 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr);
2561 2579
2562 instructions <<= return_instr; 2580 instructions <<= return_instr;
2563 2581
2564 return instructions.closed(); 2582 return instructions.closed();
2565 } 2583 }
2566 2584
2567 2585
2568 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, 2586 Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 body += NullConstant(); 3183 body += NullConstant();
3166 body += Return(dart_function.end_token_pos()); 3184 body += Return(dart_function.end_token_pos());
3167 } 3185 }
3168 3186
3169 // If functions body contains any yield points build switch statement that 3187 // If functions body contains any yield points build switch statement that
3170 // selects a continuation point based on the value of :await_jump_var. 3188 // selects a continuation point based on the value of :await_jump_var.
3171 if (!yield_continuations_.is_empty()) { 3189 if (!yield_continuations_.is_empty()) {
3172 // The code we are building will be executed right after we enter 3190 // The code we are building will be executed right after we enter
3173 // the function and before any nested contexts are allocated. 3191 // the function and before any nested contexts are allocated.
3174 // Reset current context_depth_ to match this. 3192 // Reset current context_depth_ to match this.
3175 intptr_t current_context_depth = context_depth_; 3193 const intptr_t current_context_depth = context_depth_;
3176 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); 3194 context_depth_ = scopes_->yield_jump_variable->owner()->context_level();
3177 3195
3178 // Prepend an entry corresponding to normal entry to the function. 3196 // Prepend an entry corresponding to normal entry to the function.
3179 yield_continuations_.InsertAt( 3197 yield_continuations_.InsertAt(
3180 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), 3198 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL),
3181 CatchClauseNode::kInvalidTryIndex)); 3199 CatchClauseNode::kInvalidTryIndex));
3182 yield_continuations_[0].entry->LinkTo(body.entry); 3200 yield_continuations_[0].entry->LinkTo(body.entry);
3183 3201
3184 // Build a switch statement. 3202 // Build a switch statement.
3185 Fragment dispatch; 3203 Fragment dispatch;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 3249
3232 // False branch will contain the next comparison. 3250 // False branch will contain the next comparison.
3233 dispatch = Fragment(dispatch.entry, otherwise); 3251 dispatch = Fragment(dispatch.entry, otherwise);
3234 block = otherwise; 3252 block = otherwise;
3235 } 3253 }
3236 body = dispatch; 3254 body = dispatch;
3237 3255
3238 context_depth_ = current_context_depth; 3256 context_depth_ = current_context_depth;
3239 } 3257 }
3240 3258
3259 if (FLAG_causal_async_stacks &&
3260 (dart_function.IsAsyncClosure() || dart_function.IsAsyncGenClosure())) {
3261 // The code we are building will be executed right after we enter
3262 // the function and before any nested contexts are allocated.
3263 // Reset current context_depth_ to match this.
3264 const intptr_t current_context_depth = context_depth_;
3265 context_depth_ = scopes_->yield_jump_variable->owner()->context_level();
3266
3267 Fragment instructions;
3268 LocalScope* scope = parsed_function_->node_sequence()->scope();
3269
3270 const Function& target = Function::ZoneHandle(
3271 Z, I->object_store()->async_set_thread_stack_trace());
3272 ASSERT(!target.IsNull());
3273
3274 // Fetch and load :async_stack_trace
3275 LocalVariable* async_stack_trace_var =
3276 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3277 ASSERT((async_stack_trace_var != NULL) &&
3278 async_stack_trace_var->is_captured());
3279 instructions += LoadLocal(async_stack_trace_var);
3280 instructions += PushArgument();
3281
3282 // Call _asyncSetThreadStackTrace
3283 instructions += StaticCall(TokenPosition::kNoSource, target, 1);
3284 instructions += Drop();
3285
3286 body = instructions + body;
3287 context_depth_ = current_context_depth;
3288 }
3289
3241 if (FLAG_support_debugger && function->position().IsDebugPause() && 3290 if (FLAG_support_debugger && function->position().IsDebugPause() &&
3242 !dart_function.is_native() && dart_function.is_debuggable()) { 3291 !dart_function.is_native() && dart_function.is_debuggable()) {
3243 // If a switch was added above: Start the switch by injecting a debugable 3292 // If a switch was added above: Start the switch by injecting a debugable
3244 // safepoint so stepping over an await works. 3293 // safepoint so stepping over an await works.
3245 // If not, still start the body with a debugable safepoint to ensure 3294 // If not, still start the body with a debugable safepoint to ensure
3246 // breaking on a method always happens, even if there are no 3295 // breaking on a method always happens, even if there are no
3247 // assignments/calls/runtimecalls in the first basic block. 3296 // assignments/calls/runtimecalls in the first basic block.
3248 // Place this check at the last parameter to ensure parameters 3297 // Place this check at the last parameter to ensure parameters
3249 // are in scope in the debugger at method entry. 3298 // are in scope in the debugger at method entry.
3250 const int num_params = dart_function.NumParameters(); 3299 const int num_params = dart_function.NumParameters();
(...skipping 2845 matching lines...) Expand 10 before | Expand all | Expand 10 after
6096 6145
6097 fragment_ = continuation; 6146 fragment_ = continuation;
6098 } 6147 }
6099 6148
6100 6149
6101 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, 6150 Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node,
6102 TreeNode* parent) { 6151 TreeNode* parent) {
6103 // The VM has a per-isolate table of functions indexed by the enclosing 6152 // The VM has a per-isolate table of functions indexed by the enclosing
6104 // function and token position. 6153 // function and token position.
6105 Function& function = Function::ZoneHandle(Z); 6154 Function& function = Function::ZoneHandle(Z);
6155 LocalScope* scope = NULL;
6106 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) { 6156 for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) {
6107 if (scopes_->function_scopes[i].function != node) continue; 6157 if (scopes_->function_scopes[i].function != node) continue;
6108 6158
6109 TokenPosition position = node->position(); 6159 TokenPosition position = node->position();
6110 if (parent->IsFunctionDeclaration()) { 6160 if (parent->IsFunctionDeclaration()) {
6111 position = FunctionDeclaration::Cast(parent)->position(); 6161 position = FunctionDeclaration::Cast(parent)->position();
6112 } 6162 }
6113 if (!position.IsReal()) { 6163 if (!position.IsReal()) {
6114 // Positions has to be unique in regards to the parent. 6164 // Positions has to be unique in regards to the parent.
6115 // A non-real at this point is probably -1, we cannot blindly use that 6165 // A non-real at this point is probably -1, we cannot blindly use that
6116 // as others might use it too. Create a new dummy non-real TokenPosition. 6166 // as others might use it too. Create a new dummy non-real TokenPosition.
6117 position = TokenPosition(i).ToSynthetic(); 6167 position = TokenPosition(i).ToSynthetic();
6118 } 6168 }
6119 6169
6120 // NOTE: This is not TokenPosition in the general sense! 6170 // NOTE: This is not TokenPosition in the general sense!
6121 function = I->LookupClosureFunction(parsed_function_->function(), position); 6171 function = I->LookupClosureFunction(parsed_function_->function(), position);
6172 scope = scopes_->function_scopes[i].scope;
6122 if (function.IsNull()) { 6173 if (function.IsNull()) {
6123 const dart::String* name; 6174 const dart::String* name;
6124 if (parent->IsFunctionExpression()) { 6175 if (parent->IsFunctionExpression()) {
6125 name = &Symbols::AnonymousClosure(); 6176 name = &Symbols::AnonymousClosure();
6126 } else { 6177 } else {
6127 ASSERT(parent->IsFunctionDeclaration()); 6178 ASSERT(parent->IsFunctionDeclaration());
6128 name = &H.DartSymbol( 6179 name = &H.DartSymbol(
6129 FunctionDeclaration::Cast(parent)->variable()->name()); 6180 FunctionDeclaration::Cast(parent)->variable()->name());
6130 } 6181 }
6131 // NOTE: This is not TokenPosition in the general sense! 6182 // NOTE: This is not TokenPosition in the general sense!
(...skipping 13 matching lines...) Expand all
6145 function.set_modifier(RawFunction::kAsyncGen); 6196 function.set_modifier(RawFunction::kAsyncGen);
6146 break; 6197 break;
6147 default: 6198 default:
6148 // no special modifier 6199 // no special modifier
6149 break; 6200 break;
6150 } 6201 }
6151 function.set_is_generated_body(node->async_marker() == 6202 function.set_is_generated_body(node->async_marker() ==
6152 FunctionNode::kSyncYielding); 6203 FunctionNode::kSyncYielding);
6153 6204
6154 function.set_end_token_pos(node->end_position()); 6205 function.set_end_token_pos(node->end_position());
6155 LocalScope* scope = scopes_->function_scopes[i].scope;
6156 const ContextScope& context_scope = 6206 const ContextScope& context_scope =
6157 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_)); 6207 ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_));
6158 function.set_context_scope(context_scope); 6208 function.set_context_scope(context_scope);
6159 function.set_kernel_function(node); 6209 function.set_kernel_function(node);
6160 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z), 6210 KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z),
6161 function, node, 6211 function, node,
6162 false, // is_method 6212 false, // is_method
6163 true); // is_closure 6213 true); // is_closure
6164 // Finalize function type. 6214 // Finalize function type.
6165 Type& signature_type = Type::Handle(Z, function.SignatureType()); 6215 Type& signature_type = Type::Handle(Z, function.SignatureType());
6166 signature_type ^= ClassFinalizer::FinalizeType( 6216 signature_type ^= ClassFinalizer::FinalizeType(
6167 *active_class_.klass, signature_type, ClassFinalizer::kCanonicalize); 6217 *active_class_.klass, signature_type, ClassFinalizer::kCanonicalize);
6168 function.SetSignatureType(signature_type); 6218 function.SetSignatureType(signature_type);
6169 6219
6170 I->AddClosureFunction(function); 6220 I->AddClosureFunction(function);
6171 } 6221 }
6172 break; 6222 break;
6173 } 6223 }
6174 6224
6225 Fragment instructions;
6226
6227 if (FLAG_causal_async_stacks &&
kustermann 2017/02/23 10:30:37 You can move this code to FlowGraphBuilder::BuildG
6228 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
6229 // :async_stack_trace = _asyncStackTraceHelper();
6230 const dart::Library& async_lib =
6231 dart::Library::Handle(dart::Library::AsyncLibrary());
6232 const Function& target = Function::ZoneHandle(
6233 Z,
6234 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
6235 ASSERT(!target.IsNull());
6236 instructions += StaticCall(TokenPosition::kNoSource, target, 0);
6237 LocalVariable* async_stack_trace_var =
6238 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
6239 ASSERT(async_stack_trace_var != NULL);
6240 instructions += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var);
6241 instructions += Drop();
6242 }
6243
6175 const dart::Class& closure_class = 6244 const dart::Class& closure_class =
6176 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); 6245 dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
6177 ASSERT(!closure_class.IsNull()); 6246 ASSERT(!closure_class.IsNull());
6178 Fragment instructions = AllocateObject(closure_class, function); 6247 instructions += AllocateObject(closure_class, function);
6179 LocalVariable* closure = MakeTemporary(); 6248 LocalVariable* closure = MakeTemporary();
6180 6249
6181 // TODO(27590): Generic closures need type arguments. 6250 // TODO(27590): Generic closures need type arguments.
6182 6251
6183 // Store the function and the context in the closure. 6252 // Store the function and the context in the closure.
6184 instructions += LoadLocal(closure); 6253 instructions += LoadLocal(closure);
6185 instructions += Constant(function); 6254 instructions += Constant(function);
6186 instructions += StoreInstanceField(Closure::function_offset()); 6255 instructions += StoreInstanceField(Closure::function_offset());
6187 6256
6188 instructions += LoadLocal(closure); 6257 instructions += LoadLocal(closure);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
6299 thread->clear_sticky_error(); 6368 thread->clear_sticky_error();
6300 return error.raw(); 6369 return error.raw();
6301 } 6370 }
6302 } 6371 }
6303 6372
6304 6373
6305 } // namespace kernel 6374 } // namespace kernel
6306 } // namespace dart 6375 } // namespace dart
6307 6376
6308 #endif // !defined(DART_PRECOMPILED_RUNTIME) 6377 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « pkg/kernel/lib/transformations/continuation.dart ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698