Chromium Code Reviews| Index: runtime/vm/kernel_to_il.cc |
| diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc |
| index 8e251bbee1a45bc62689bff6f61a552e9b305773..0e1d4710036bf4a9ad45fe375ab4b982b5253351 100644 |
| --- a/runtime/vm/kernel_to_il.cc |
| +++ b/runtime/vm/kernel_to_il.cc |
| @@ -720,6 +720,15 @@ void ScopeBuilder::VisitFunctionNode(FunctionNode* node) { |
| scope_->CaptureVariable(temp); |
| } |
| } |
| + if (FLAG_causal_async_stacks) { |
| + // TODO(28777): Either remove the variable here, or update the dart side |
|
Kevin Millikin (Google)
2017/02/22 10:42:17
The comment is confusing. It's not entirely clear
jensj
2017/02/23 09:40:26
I have attempted to move the call to _asyncStackTr
|
| + // so we don't always generate it if this flag is not set. |
| + LocalVariable* temp = |
| + scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true); |
| + if (temp != NULL) { |
| + scope_->CaptureVariable(temp); |
| + } |
| + } |
| } |
| } |
| @@ -2555,6 +2564,17 @@ Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); |
| } |
| + if (FLAG_causal_async_stacks && |
| + function.name() == Symbols::AsyncOperation().raw()) { |
|
Kevin Millikin (Google)
2017/02/22 10:42:18
We should set the function to be correctly IsAsync
jensj
2017/02/23 09:40:26
Done.
|
| + // We are returning from an asynchronous closure. Before we do that, be |
| + // sure to clear the thread's asynchronous stack trace. |
| + const Function& target = Function::ZoneHandle( |
| + Z, I->object_store()->async_clear_thread_stack_trace()); |
| + ASSERT(!target.IsNull()); |
| + instructions += StaticCall(TokenPosition::kNoSource, target, 0); |
| + instructions += Drop(); |
| + } |
| + |
| ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| @@ -3171,7 +3191,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFunction(FunctionNode* function, |
| // The code we are building will be executed right after we enter |
| // the function and before any nested contexts are allocated. |
| // Reset current context_depth_ to match this. |
| - intptr_t current_context_depth = context_depth_; |
| + const intptr_t current_context_depth = context_depth_; |
| context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); |
| // Prepend an entry corresponding to normal entry to the function. |
| @@ -3237,6 +3257,37 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFunction(FunctionNode* function, |
| context_depth_ = current_context_depth; |
| } |
| + if (FLAG_causal_async_stacks && |
| + dart_function.name() == Symbols::AsyncOperation().raw()) { |
|
Kevin Millikin (Google)
2017/02/22 10:42:17
Also here, I'd rather not use the name if we don't
jensj
2017/02/23 09:40:26
Done.
|
| + // The code we are building will be executed right after we enter |
| + // the function and before any nested contexts are allocated. |
| + // Reset current context_depth_ to match this. |
| + const intptr_t current_context_depth = context_depth_; |
| + context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); |
| + |
| + Fragment instructions; |
| + LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| + |
| + const Function& target = Function::ZoneHandle( |
| + Z, I->object_store()->async_set_thread_stack_trace()); |
| + ASSERT(!target.IsNull()); |
| + |
| + // Fetch and load :async_stack_trace |
| + LocalVariable* async_stack_trace_var = |
| + scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
| + ASSERT((async_stack_trace_var != NULL) && |
| + async_stack_trace_var->is_captured()); |
| + instructions += LoadLocal(async_stack_trace_var); |
| + instructions += PushArgument(); |
| + |
| + // Call _asyncSetThreadStackTrace |
| + instructions += StaticCall(TokenPosition::kNoSource, target, 1); |
| + instructions += Drop(); |
| + |
| + body = instructions + body; |
| + context_depth_ = current_context_depth; |
| + } |
| + |
| if (FLAG_support_debugger && function->position().IsDebugPause() && |
| !dart_function.is_native() && dart_function.is_debuggable()) { |
| // If a switch was added above: Start the switch by injecting a debugable |
| @@ -6131,7 +6182,8 @@ Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node, |
| // NOTE: This is not TokenPosition in the general sense! |
| function = Function::NewClosureFunction( |
| *name, parsed_function_->function(), position); |
| - function.set_is_debuggable(node->debuggable()); |
| + function.set_is_debuggable(node->original_async_marker() == |
| + FunctionNode::kSync); |
| function.set_end_token_pos(node->end_position()); |
| LocalScope* scope = scopes_->function_scopes[i].scope; |
| const ContextScope& context_scope = |