Enable causal stacktrace in kernel

R=kustermann@google.com

Review-Url: https://codereview.chromium.org/2690873005 .
This commit is contained in:
Jens Johansen
2017-02-15 14:17:29 +01:00
parent 43932d0bb6
commit b29829660b
3 changed files with 69 additions and 4 deletions
@@ -198,6 +198,8 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
new VariableDeclaration(":async_op_then");
final VariableDeclaration catchErrorContinuationVariable =
new VariableDeclaration(":async_op_error");
final VariableDeclaration asyncStackTrace =
new VariableDeclaration(":async_stack_trace");
LabeledStatement labeledBody;
@@ -215,6 +217,9 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
// var :async_op_error;
statements.add(catchErrorContinuationVariable);
// var :async_stack_trace;
statements.add(asyncStackTrace);
// :async_op([:result, :exception, :stack_trace]) {
// modified <node.body>;
// }
@@ -258,6 +263,13 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase {
new VariableSet(
catchErrorContinuationVariable, boundCatchErrorClosure));
statements.add(catchErrorClosureVariableAssign);
// :async_stack_trace = _asyncStackTraceHelper();
final boundAsyncStackTrace = new StaticInvocation(
helper.asyncStackTraceHelper, new Arguments.empty());
final asyncStackTraceVariableAssign = new ExpressionStatement(
new VariableSet(asyncStackTrace, boundAsyncStackTrace));
statements.add(asyncStackTraceVariableAssign);
}
Statement buildWrappedBody() {
@@ -874,6 +886,7 @@ class HelperNodes {
final Constructor streamIteratorConstructor;
final Procedure asyncThenWrapper;
final Procedure asyncErrorWrapper;
final Procedure asyncStackTraceHelper;
final Procedure awaitHelper;
final CoreTypes coreTypes;
@@ -891,6 +904,7 @@ class HelperNodes {
this.streamControllerConstructor,
this.asyncThenWrapper,
this.asyncErrorWrapper,
this.asyncStackTraceHelper,
this.awaitHelper,
this.coreTypes);
@@ -973,6 +987,7 @@ class HelperNodes {
findConstructor(streamControllerClass, ''),
findProcedure(asyncLibrary, '_asyncThenWrapperHelper'),
findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'),
findProcedure(asyncLibrary, '_asyncStackTraceHelper'),
findProcedure(asyncLibrary, '_awaitHelper'),
new CoreTypes(program));
}
+52 -1
View File
@@ -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
// 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()) {
// 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()) {
// 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
+2 -3
View File
@@ -44,7 +44,7 @@ vm/debug_break_enabled_vm_test/01: CompileTimeError
vm/debug_break_enabled_vm_test/none: CompileTimeError
vm/reflect_core_vm_test: CompileTimeError
vm/regress_27201_test: CompileTimeError
vm/regress_28325_test: RuntimeError # Issue 28055.
# vm/regress_28325_test: RuntimeError # Issue 28055. Passes by mistake.
# dartk: JIT failures
[ $compiler == dartk && $runtime == vm ]
@@ -203,9 +203,8 @@ library_env_test/has_no_mirror_support: RuntimeError
main_not_a_function_test/01: Crash
redirecting_factory_reflection_test: RuntimeError
# Casual async stack traces are not implemented for Kernel.
# Casual async stack traces does not give exactly same stacktrace on kernel
vm/causal_async_exception_stack_test: RuntimeError
vm/causal_async_exception_stack2_test: RuntimeError
# dartk: JIT failures (debug)
[ $compiler == dartk && $runtime == vm && $mode == debug ]