Chromium Code Reviews| Index: runtime/vm/debugger.cc |
| diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc |
| index 4253eca091d89ff9a06aa966decee5ef35bafe84..ff3821a1f9929e237e999cb6865596d0299ae692 100644 |
| --- a/runtime/vm/debugger.cc |
| +++ b/runtime/vm/debugger.cc |
| @@ -12,6 +12,7 @@ |
| #include "vm/compiler.h" |
| #include "vm/dart_entry.h" |
| #include "vm/deopt_instructions.h" |
| +#include "vm/disassembler.h" |
| #include "vm/flags.h" |
| #include "vm/globals.h" |
| #include "vm/json_stream.h" |
| @@ -264,6 +265,7 @@ ActivationFrame::ActivationFrame(uword pc, |
| token_pos_initialized_(false), |
| token_pos_(TokenPosition::kNoSource), |
| try_index_(-1), |
| + deopt_id_(Thread::kNoDeoptId), |
| line_number_(-1), |
| column_number_(-1), |
| context_level_(-1), |
| @@ -611,6 +613,7 @@ TokenPosition ActivationFrame::TokenPos() { |
| if (iter.PcOffset() == pc_offset) { |
| try_index_ = iter.TryIndex(); |
| token_pos_ = iter.TokenPos(); |
| + deopt_id_ = iter.DeoptId(); |
| break; |
| } |
| } |
| @@ -627,6 +630,14 @@ intptr_t ActivationFrame::TryIndex() { |
| } |
| +intptr_t ActivationFrame::DeoptId() { |
| + if (!token_pos_initialized_) { |
| + TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
| + } |
| + return deopt_id_; |
| +} |
| + |
| + |
| intptr_t ActivationFrame::LineNumber() { |
| // Compute line number lazily since it causes scanning of the script. |
| if ((line_number_ < 0) && TokenPos().IsSourcePosition()) { |
| @@ -683,36 +694,45 @@ intptr_t ActivationFrame::ContextLevel() { |
| const Context& ctx = GetSavedCurrentContext(); |
| if (context_level_ < 0 && !ctx.IsNull()) { |
| ASSERT(!code_.is_optimized()); |
| - context_level_ = 0; |
| - // TODO(hausner): What to do if there is no descriptor entry |
| - // for the code position of the frame? For now say we are at context |
| - // level 0. |
| - TokenPos(); |
| - if (token_pos_ == TokenPosition::kNoSource) { |
| - // No PcDescriptor. |
| - return context_level_; |
| + |
| + intptr_t deopt_id = DeoptId(); |
| + if (deopt_id == Thread::kNoDeoptId) { |
| + DisassembleToStdout formatter; |
| + code().Disassemble(&formatter); |
| + PcDescriptors::Handle(code().pc_descriptors()).Print(); |
| + FATAL2("Missing deopt id for pc %" Px " in %s", pc_, |
| + function().ToQualifiedCString()); |
|
Vyacheslav Egorov (Google)
2017/06/01 12:32:41
Maybe move this code to a helper function.
Then
rmacnak
2017/06/01 19:26:09
Done like PrintContextMismatch.
|
| } |
| - ASSERT(!pc_desc_.IsNull()); |
| - TokenPosition innermost_begin_pos = TokenPosition::kMinSource; |
| - TokenPosition activation_token_pos = TokenPos().FromSynthetic(); |
| - ASSERT(activation_token_pos.IsReal()); |
| GetVarDescriptors(); |
| intptr_t var_desc_len = var_descriptors_.Length(); |
| + bool found = false; |
| for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| RawLocalVarDescriptors::VarInfo var_info; |
| var_descriptors_.GetInfo(cur_idx, &var_info); |
| const int8_t kind = var_info.kind(); |
| if ((kind == RawLocalVarDescriptors::kContextLevel) && |
| - (var_info.begin_pos <= activation_token_pos) && |
| - (activation_token_pos < var_info.end_pos)) { |
| - // This var_descriptors_ entry is a context scope which is in scope |
| - // of the current token position. Now check whether it is shadowing |
| - // the previous context scope. |
| - if (innermost_begin_pos < var_info.begin_pos) { |
| - innermost_begin_pos = var_info.begin_pos; |
| - context_level_ = var_info.index(); |
| - } |
| + (deopt_id >= var_info.begin_pos.value()) && |
| + (deopt_id <= var_info.end_pos.value())) { |
| + context_level_ = var_info.index(); |
| + found = true; |
| + break; |
| + } |
| + } |
| + if (!found) { |
| + DisassembleToStdout formatter; |
| + code().Disassemble(&formatter); |
| + PcDescriptors::Handle(code().pc_descriptors()).Print(); |
| + |
| + StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, |
| + Thread::Current(), |
| + StackFrameIterator::kNoCrossThreadIteration); |
| + StackFrame* frame = frames.NextFrame(); |
| + while (frame != NULL) { |
| + OS::PrintErr("%s\n", frame->ToCString()); |
| + frame = frames.NextFrame(); |
| } |
| + FATAL3("Missing context level for deopt_id=%" Pd ", pc=%" Px " in %s", |
| + deopt_id, pc_, function().ToQualifiedCString()); |
| } |
| ASSERT(context_level_ >= 0); |
| } |