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

Unified Diff: runtime/vm/debugger.cc

Issue 2718353002: Revert "Track the 'awaiter return' call stack..." (Closed)
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/exceptions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/debugger.cc
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 5cf5419f449621b75e7f9f63387cb4fe403fa3e9..a74a0f53fb38beae9814b94fdaa9e8c8f4466b7e 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -259,7 +259,7 @@ ActivationFrame::ActivationFrame(uword pc,
ctx_(Context::ZoneHandle()),
code_(Code::ZoneHandle(code.raw())),
function_(Function::ZoneHandle(code.function())),
- live_frame_((kind == kRegular) || (kind == kAsyncActivation)),
+ live_frame_(kind == kRegular),
token_pos_initialized_(false),
token_pos_(TokenPosition::kNoSource),
try_index_(-1),
@@ -297,37 +297,6 @@ ActivationFrame::ActivationFrame(Kind kind)
desc_indices_(8),
pc_desc_(PcDescriptors::ZoneHandle()) {}
-
-ActivationFrame::ActivationFrame(const Closure& async_activation)
- : pc_(0),
- fp_(0),
- sp_(0),
- ctx_(Context::ZoneHandle()),
- code_(Code::ZoneHandle()),
- function_(Function::ZoneHandle()),
- live_frame_(false),
- token_pos_initialized_(false),
- token_pos_(TokenPosition::kNoSource),
- try_index_(-1),
- line_number_(-1),
- column_number_(-1),
- context_level_(-1),
- deopt_frame_(Array::ZoneHandle()),
- deopt_frame_offset_(0),
- kind_(kAsyncActivation),
- vars_initialized_(false),
- var_descriptors_(LocalVarDescriptors::ZoneHandle()),
- desc_indices_(8),
- pc_desc_(PcDescriptors::ZoneHandle()) {
- // Extract the function and the code from the asynchronous activation.
- function_ = async_activation.function();
- code_ = function_.unoptimized_code();
- ctx_ = async_activation.context();
- ASSERT(fp_ == 0);
- ASSERT(!ctx_.IsNull());
-}
-
-
bool Debugger::NeedsIsolateEvents() {
return ((isolate_ != Dart::vm_isolate()) &&
!ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
@@ -710,231 +679,6 @@ intptr_t ActivationFrame::ContextLevel() {
return context_level_;
}
-RawObject* ActivationFrame::GetAsyncCompleter() {
- if (!function_.IsAsyncClosure()) {
- return Object::null();
- }
- GetVarDescriptors();
- intptr_t var_desc_len = var_descriptors_.Length();
- if (!live_frame_) {
- // Not actually on the stack. Pull it out of the closure's context.
- intptr_t var_desc_len = var_descriptors_.Length();
- for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
- var_descriptors_.GetInfo(i, &var_info);
- const int8_t kind = var_info.kind();
- if (var_descriptors_.GetName(i) == Symbols::AsyncCompleter().raw()) {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
- ASSERT(!ctx_.IsNull());
- return ctx_.At(var_info.index());
- }
- }
- } else {
- ASSERT(fp() != 0);
- // On the stack.
- for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
- var_descriptors_.GetInfo(i, &var_info);
- if (var_descriptors_.GetName(i) == Symbols::AsyncCompleter().raw()) {
- const int8_t kind = var_info.kind();
- if (kind == RawLocalVarDescriptors::kStackVar) {
- return GetStackVar(var_info.index());
- } else {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
- return GetContextVar(var_info.scope_id, var_info.index());
- }
- }
- }
- }
- return Object::null();
-}
-
-
-RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
- const Class& sync_completer_cls = Class::Handle(completer.clazz());
- ASSERT(!sync_completer_cls.IsNull());
- const Class& completer_cls = Class::Handle(sync_completer_cls.SuperClass());
- const Field& future_field =
- Field::Handle(completer_cls.LookupInstanceFieldAllowPrivate(
- Symbols::CompleterFuture()));
- ASSERT(!future_field.IsNull());
- Instance& future = Instance::Handle();
- future ^= Instance::Cast(completer).GetField(future_field);
- ASSERT(!future.IsNull());
- const Class& future_cls = Class::Handle(future.clazz());
- ASSERT(!future_cls.IsNull());
- const Field& awaiter_field = Field::Handle(
- future_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
- ASSERT(!awaiter_field.IsNull());
- return future.GetField(awaiter_field);
-}
-
-
-RawObject* ActivationFrame::GetAsyncStreamControllerStream() {
- if (!function_.IsAsyncGenClosure()) {
- return Object::null();
- }
- GetVarDescriptors();
- intptr_t var_desc_len = var_descriptors_.Length();
- if (!live_frame_) {
- // Not actually on the stack. Pull it out of the closure's context.
- intptr_t var_desc_len = var_descriptors_.Length();
- for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
- var_descriptors_.GetInfo(i, &var_info);
- const int8_t kind = var_info.kind();
- if (var_descriptors_.GetName(i) == Symbols::ControllerStream().raw()) {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
- ASSERT(!ctx_.IsNull());
- return ctx_.At(var_info.index());
- }
- }
- } else {
- ASSERT(fp() != 0);
- // On the stack.
- for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
- var_descriptors_.GetInfo(i, &var_info);
- if (var_descriptors_.GetName(i) == Symbols::ControllerStream().raw()) {
- const int8_t kind = var_info.kind();
- if (kind == RawLocalVarDescriptors::kStackVar) {
- return GetStackVar(var_info.index());
- } else {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
- return GetContextVar(var_info.scope_id, var_info.index());
- }
- }
- }
- }
- return Object::null();
-}
-
-
-RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
- const Object& stream) {
- const Class& stream_cls = Class::Handle(stream.clazz());
- ASSERT(!stream_cls.IsNull());
- const Class& stream_impl_cls = Class::Handle(stream_cls.SuperClass());
- const Field& awaiter_field = Field::Handle(
- stream_impl_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
- ASSERT(!awaiter_field.IsNull());
- return Instance::Cast(stream).GetField(awaiter_field);
-}
-
-
-RawObject* ActivationFrame::GetAsyncAwaiter() {
- const Object& completer = Object::Handle(GetAsyncCompleter());
- if (!completer.IsNull()) {
- return GetAsyncCompleterAwaiter(completer);
- }
- const Object& async_stream_controller_stream =
- Object::Handle(GetAsyncStreamControllerStream());
- if (!async_stream_controller_stream.IsNull()) {
- return GetAsyncStreamControllerStreamAwaiter(
- async_stream_controller_stream);
- }
- return Object::null();
-}
-
-
-bool ActivationFrame::HandlesException(const Instance& exc_obj) {
- intptr_t try_index = TryIndex();
- if (try_index < 0) {
- return false;
- }
- ExceptionHandlers& handlers = ExceptionHandlers::Handle();
- Array& handled_types = Array::Handle();
- AbstractType& type = Type::Handle();
- const TypeArguments& no_instantiator = TypeArguments::Handle();
- const intptr_t try_index_threshold = CatchClauseNode::kImplicitAsyncTryIndex;
- const bool is_async =
- function().IsAsyncClosure() || function().IsAsyncGenClosure();
- handlers = code().exception_handlers();
- ASSERT(!handlers.IsNull());
- intptr_t num_handlers_checked = 0;
- while (try_index >= try_index_threshold) {
- // Detect circles in the exception handler data.
- num_handlers_checked++;
- ASSERT(num_handlers_checked <= handlers.num_entries());
- // Only consider user written handlers for async methods.
- if (!is_async || !handlers.IsGenerated(try_index)) {
- handled_types = handlers.GetHandledTypes(try_index);
- const intptr_t num_types = handled_types.Length();
- for (intptr_t k = 0; k < num_types; k++) {
- type ^= handled_types.At(k);
- ASSERT(!type.IsNull());
- // Uninstantiated types are not added to ExceptionHandlers data.
- ASSERT(type.IsInstantiated());
- if (type.IsMalformed()) {
- continue;
- }
- if (type.IsDynamicType()) {
- return true;
- }
- if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
- return true;
- }
- }
- }
- try_index = handlers.OuterTryIndex(try_index);
- }
- return false;
-}
-
-
-void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
- // Attempt to determine the token position from the async closure.
- ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
- // This should only be called on frames that aren't active on the stack.
- ASSERT(fp() == 0);
- const Array& await_to_token_map =
- Array::Handle(code_.await_token_positions());
- if (await_to_token_map.IsNull()) {
- // No mapping.
- return;
- }
- GetVarDescriptors();
- GetPcDescriptors();
- intptr_t var_desc_len = var_descriptors_.Length();
- intptr_t await_jump_var = -1;
- for (intptr_t i = 0; i < var_desc_len; i++) {
- RawLocalVarDescriptors::VarInfo var_info;
- var_descriptors_.GetInfo(i, &var_info);
- const int8_t kind = var_info.kind();
- if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) {
- ASSERT(kind == RawLocalVarDescriptors::kContextVar);
- ASSERT(!ctx_.IsNull());
- Object& await_jump_index = Object::Handle(ctx_.At(var_info.index()));
- ASSERT(await_jump_index.IsSmi());
- await_jump_var = Smi::Cast(await_jump_index).Value();
- }
- }
- if (await_jump_var < 0) {
- return;
- }
- ASSERT(await_jump_var < await_to_token_map.Length());
- const Object& token_pos =
- Object::Handle(await_to_token_map.At(await_jump_var));
- if (token_pos.IsNull()) {
- return;
- }
- ASSERT(token_pos.IsSmi());
- token_pos_ = TokenPosition(Smi::Cast(token_pos).Value());
- token_pos_initialized_ = true;
- PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
- while (iter.MoveNext()) {
- if (iter.TokenPos() == token_pos_) {
- // Match the lowest try index at this token position.
- // TODO(johnmccutchan): Is this heuristic precise enough?
- if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) {
- if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) {
- try_index_ = iter.TryIndex();
- }
- }
- }
- }
-}
-
// Get the saved current context of this activation.
const Context& ActivationFrame::GetSavedCurrentContext() {
@@ -980,10 +724,35 @@ RawObject* ActivationFrame::GetAsyncOperation() {
ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
const Instance& exc_obj) const {
+ ExceptionHandlers& handlers = ExceptionHandlers::Handle();
+ Array& handled_types = Array::Handle();
+ AbstractType& type = Type::Handle();
+ const TypeArguments& no_instantiator = TypeArguments::Handle();
for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) {
ActivationFrame* frame = FrameAt(frame_index);
- if (frame->HandlesException(exc_obj)) {
- return frame;
+ intptr_t try_index = frame->TryIndex();
+ if (try_index < 0) continue;
+ handlers = frame->code().exception_handlers();
+ ASSERT(!handlers.IsNull());
+ intptr_t num_handlers_checked = 0;
+ while (try_index >= 0) {
+ // Detect circles in the exception handler data.
+ num_handlers_checked++;
+ ASSERT(num_handlers_checked <= handlers.num_entries());
+ handled_types = handlers.GetHandledTypes(try_index);
+ const intptr_t num_types = handled_types.Length();
+ for (intptr_t k = 0; k < num_types; k++) {
+ type ^= handled_types.At(k);
+ ASSERT(!type.IsNull());
+ // Uninstantiated types are not added to ExceptionHandlers data.
+ ASSERT(type.IsInstantiated());
+ if (type.IsMalformed()) continue;
+ if (type.IsDynamicType()) return frame;
+ if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
+ return frame;
+ }
+ }
+ try_index = handlers.OuterTryIndex(try_index);
}
}
return NULL;
@@ -1383,10 +1152,7 @@ void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) {
TokenPosition visible_end_token_pos;
VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos,
&visible_end_token_pos, &var_value);
- if ((var_name.raw() != Symbols::AsyncOperation().raw()) &&
- (var_name.raw() != Symbols::AsyncCompleter().raw()) &&
- (var_name.raw() != Symbols::ControllerStream().raw()) &&
- (var_name.raw() != Symbols::AwaitJumpVar().raw())) {
+ if (var_name.raw() != Symbols::AsyncOperation().raw()) {
JSONObject jsvar(&jsvars);
jsvar.AddProperty("type", "BoundVariable");
var_name = String::ScrubName(var_name);
@@ -1782,12 +1548,10 @@ ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
StackFrame* frame,
const Code& code,
const Array& deopt_frame,
- intptr_t deopt_frame_offset,
- ActivationFrame::Kind kind) {
+ intptr_t deopt_frame_offset) {
ASSERT(code.ContainsInstructionAt(pc));
- ActivationFrame* activation =
- new ActivationFrame(pc, frame->fp(), frame->sp(), code, deopt_frame,
- deopt_frame_offset, kind);
+ ActivationFrame* activation = new ActivationFrame(
+ pc, frame->fp(), frame->sp(), code, deopt_frame, deopt_frame_offset);
if (FLAG_trace_debugger_stacktrace) {
const Context& ctx = activation->GetSavedCurrentContext();
OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString());
@@ -1964,64 +1728,6 @@ DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() {
return stack_trace;
}
-
-DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
- if (!FLAG_causal_async_stacks) {
- return NULL;
- }
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- Isolate* isolate = thread->isolate();
- DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
-
- StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames);
-
- Code& code = Code::Handle(zone);
- Function& function = Function::Handle(zone);
- Code& inlined_code = Code::Handle(zone);
- Closure& async_activation = Closure::Handle(zone);
- Array& deopt_frame = Array::Handle(zone);
-
- for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
- frame = iterator.NextFrame()) {
- ASSERT(frame->IsValid());
- if (frame->IsDartFrame()) {
- code = frame->LookupDartCode();
- function = code.function();
- if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
- ActivationFrame* activation = CollectDartFrame(
- isolate, frame->pc(), frame, code, Object::null_array(), 0,
- ActivationFrame::kAsyncActivation);
- ASSERT(activation != NULL);
- stack_trace->AddActivation(activation);
- // Grab the awaiter.
- async_activation ^= activation->GetAsyncAwaiter();
- break;
- } else {
- AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
- &inlined_code, &deopt_frame);
- }
- }
- }
-
- // Return NULL to indicate that there is no useful information in this stack
- // trace because we never found an awaiter.
- if (async_activation.IsNull()) {
- return NULL;
- }
-
- // Append the awaiter return call stack.
- while (!async_activation.IsNull()) {
- ActivationFrame* activation = new ActivationFrame(async_activation);
- async_activation ^= activation->GetAsyncAwaiter();
- activation->ExtractTokenPositionFromAsyncClosure();
- stack_trace->AddActivation(activation);
- }
-
- return stack_trace;
-}
-
-
ActivationFrame* Debugger::TopDartFrame() const {
StackFrameIterator iterator(false);
StackFrame* frame = iterator.NextFrame();
@@ -2122,29 +1828,6 @@ Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const {
}
-bool Debugger::ShouldPauseOnAsyncException(DebuggerStackTrace* stack_trace,
- const Instance& exc) {
- if (exc_pause_info_ == kNoPauseOnExceptions) {
- return false;
- }
- if (exc_pause_info_ == kPauseOnAllExceptions) {
- return true;
- }
- ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions);
- for (intptr_t i = 0; i < stack_trace->Length(); i++) {
- ActivationFrame* frame = stack_trace->FrameAt(i);
- if (frame->HandlesException(exc)) {
- if (FLAG_verbose_debug) {
- OS::PrintErr("%s is caught by frame %s\n", exc.ToCString(),
- frame->ToCString());
- }
- return false;
- }
- }
- return true;
-}
-
-
bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
const Instance& exception) {
if (exc_pause_info_ == kNoPauseOnExceptions) {
@@ -2176,16 +1859,9 @@ void Debugger::PauseException(const Instance& exc) {
(exc_pause_info_ == kNoPauseOnExceptions)) {
return;
}
- DebuggerStackTrace* awaiter_stack_trace = CollectAwaiterReturnStackTrace();
DebuggerStackTrace* stack_trace = CollectStackTrace();
- if (awaiter_stack_trace != NULL) {
- if (!ShouldPauseOnAsyncException(awaiter_stack_trace, exc)) {
- return;
- }
- } else {
- if (!ShouldPauseOnException(stack_trace, exc)) {
- return;
- }
+ if (!ShouldPauseOnException(stack_trace, exc)) {
+ return;
}
ServiceEvent event(isolate_, ServiceEvent::kPauseException);
event.set_exception(&exc);
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/exceptions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698