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 984de1d4aeabf6f9dda81ac56c48f9fd6ca966c9..d0ecc489ceefba12a7dfcb1dc62c2e2cff04b2ae 100644 |
| --- a/runtime/vm/kernel_to_il.cc |
| +++ b/runtime/vm/kernel_to_il.cc |
| @@ -720,6 +720,13 @@ void ScopeBuilder::VisitFunctionNode(FunctionNode* node) { |
| scope_->CaptureVariable(temp); |
| } |
| } |
| + if (FLAG_causal_async_stacks) { |
| + LocalVariable* temp = |
| + scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true); |
| + if (temp != NULL) { |
| + scope_->CaptureVariable(temp); |
| + } |
| + } |
| } |
| } |
| @@ -2555,6 +2562,21 @@ Fragment FlowGraphBuilder::Return(TokenPosition position) { |
| new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); |
| } |
| + if (FLAG_causal_async_stacks && |
| + function.name() == Symbols::AsyncOperation().raw()) { |
| + // We are returning from an asynchronous closure. Before we do that, be |
| + // sure to clear the thread's asynchronous stack trace. |
| + const Function& async_clear_thread_stack_trace = Function::ZoneHandle( |
| + Z, I->object_store()->async_clear_thread_stack_trace()); |
| + ZoneGrowableArray<PushArgumentInstr*>* no_arguments = |
| + new (Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
| + StaticCallInstr* call_async_clear_thread_stack_trace = new (Z) |
| + StaticCallInstr(TokenPosition::kNoSource, |
| + async_clear_thread_stack_trace, Object::null_array(), |
| + no_arguments, ic_data_array_); |
| + instructions <<= call_async_clear_thread_stack_trace; |
|
kustermann
2017/02/14 14:45:53
Could you rewrite this using our helper functions,
jensj
2017/02/15 11:29:53
Done.
|
| + } |
| + |
| ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| @@ -3237,6 +3259,39 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFunction(FunctionNode* function, |
| context_depth_ = current_context_depth; |
| } |
| + if (FLAG_causal_async_stacks && |
| + dart_function.name() == Symbols::AsyncOperation().raw()) { |
| + // 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_; |
|
kustermann
2017/02/14 14:45:53
nit: const (maybe also from the code you copied it
jensj
2017/02/15 11:29:53
Done.
|
| + context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); |
| + |
| + Fragment instructions; |
| + LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| + // Fetch the :async_stack_trace variable and store it into the thread. |
|
kustermann
2017/02/14 14:45:53
Could you add empty lines before comments like thi
jensj
2017/02/15 11:29:53
Done.
|
| + LocalVariable* async_stack_trace_var = |
| + scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
| + ASSERT((async_stack_trace_var != NULL) && |
| + async_stack_trace_var->is_captured()); |
| + // Load :async_stack_trace |
| + instructions += LoadLocal(async_stack_trace_var); |
| + instructions += PushArgument(); |
| + // Setup arguments for _asyncSetThreadStackTrace. |
| + ArgumentArray arguments = GetArguments(1); |
| + |
| + const Function& async_set_thread_stack_trace = Function::ZoneHandle( |
| + Z, I->object_store()->async_set_thread_stack_trace()); |
| + ASSERT(!async_set_thread_stack_trace.IsNull()); |
| + // Call _asyncSetThreadStackTrace |
| + StaticCallInstr* call_async_set_thread_stack_trace = new (Z) |
| + StaticCallInstr(TokenPosition::kNoSource, async_set_thread_stack_trace, |
| + Object::null_array(), arguments, ic_data_array_); |
| + instructions <<= call_async_set_thread_stack_trace; |
| + body = instructions + body; |
|
kustermann
2017/02/14 14:45:53
Could you also use StaticCall here
i.e. replace m
jensj
2017/02/15 11:29:53
Done.
|
| + 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 |