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); |
} |