| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "platform/address_sanitizer.h" | 9 #include "platform/address_sanitizer.h" |
| 10 | 10 |
| 11 #include "vm/code_patcher.h" | 11 #include "vm/code_patcher.h" |
| 12 #include "vm/compiler.h" | 12 #include "vm/compiler.h" |
| 13 #include "vm/dart_entry.h" | 13 #include "vm/dart_entry.h" |
| 14 #include "vm/deopt_instructions.h" | 14 #include "vm/deopt_instructions.h" |
| 15 #include "vm/disassembler.h" |
| 15 #include "vm/flags.h" | 16 #include "vm/flags.h" |
| 16 #include "vm/globals.h" | 17 #include "vm/globals.h" |
| 17 #include "vm/json_stream.h" | 18 #include "vm/json_stream.h" |
| 18 #include "vm/longjump.h" | 19 #include "vm/longjump.h" |
| 19 #include "vm/message_handler.h" | 20 #include "vm/message_handler.h" |
| 20 #include "vm/object.h" | 21 #include "vm/object.h" |
| 21 #include "vm/object_store.h" | 22 #include "vm/object_store.h" |
| 22 #include "vm/os.h" | 23 #include "vm/os.h" |
| 23 #include "vm/parser.h" | 24 #include "vm/parser.h" |
| 24 #include "vm/port.h" | 25 #include "vm/port.h" |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 : pc_(pc), | 258 : pc_(pc), |
| 258 fp_(fp), | 259 fp_(fp), |
| 259 sp_(sp), | 260 sp_(sp), |
| 260 ctx_(Context::ZoneHandle()), | 261 ctx_(Context::ZoneHandle()), |
| 261 code_(Code::ZoneHandle(code.raw())), | 262 code_(Code::ZoneHandle(code.raw())), |
| 262 function_(Function::ZoneHandle(code.function())), | 263 function_(Function::ZoneHandle(code.function())), |
| 263 live_frame_((kind == kRegular) || (kind == kAsyncActivation)), | 264 live_frame_((kind == kRegular) || (kind == kAsyncActivation)), |
| 264 token_pos_initialized_(false), | 265 token_pos_initialized_(false), |
| 265 token_pos_(TokenPosition::kNoSource), | 266 token_pos_(TokenPosition::kNoSource), |
| 266 try_index_(-1), | 267 try_index_(-1), |
| 268 deopt_id_(Thread::kNoDeoptId), |
| 267 line_number_(-1), | 269 line_number_(-1), |
| 268 column_number_(-1), | 270 column_number_(-1), |
| 269 context_level_(-1), | 271 context_level_(-1), |
| 270 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), | 272 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), |
| 271 deopt_frame_offset_(deopt_frame_offset), | 273 deopt_frame_offset_(deopt_frame_offset), |
| 272 kind_(kind), | 274 kind_(kind), |
| 273 vars_initialized_(false), | 275 vars_initialized_(false), |
| 274 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 276 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
| 275 desc_indices_(8), | 277 desc_indices_(8), |
| 276 pc_desc_(PcDescriptors::ZoneHandle()) {} | 278 pc_desc_(PcDescriptors::ZoneHandle()) {} |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 if (!token_pos_initialized_) { | 606 if (!token_pos_initialized_) { |
| 605 token_pos_initialized_ = true; | 607 token_pos_initialized_ = true; |
| 606 token_pos_ = TokenPosition::kNoSource; | 608 token_pos_ = TokenPosition::kNoSource; |
| 607 GetPcDescriptors(); | 609 GetPcDescriptors(); |
| 608 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); | 610 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); |
| 609 uword pc_offset = pc_ - code().PayloadStart(); | 611 uword pc_offset = pc_ - code().PayloadStart(); |
| 610 while (iter.MoveNext()) { | 612 while (iter.MoveNext()) { |
| 611 if (iter.PcOffset() == pc_offset) { | 613 if (iter.PcOffset() == pc_offset) { |
| 612 try_index_ = iter.TryIndex(); | 614 try_index_ = iter.TryIndex(); |
| 613 token_pos_ = iter.TokenPos(); | 615 token_pos_ = iter.TokenPos(); |
| 616 deopt_id_ = iter.DeoptId(); |
| 614 break; | 617 break; |
| 615 } | 618 } |
| 616 } | 619 } |
| 617 } | 620 } |
| 618 return token_pos_; | 621 return token_pos_; |
| 619 } | 622 } |
| 620 | 623 |
| 621 | 624 |
| 622 intptr_t ActivationFrame::TryIndex() { | 625 intptr_t ActivationFrame::TryIndex() { |
| 623 if (!token_pos_initialized_) { | 626 if (!token_pos_initialized_) { |
| 624 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. | 627 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
| 625 } | 628 } |
| 626 return try_index_; | 629 return try_index_; |
| 627 } | 630 } |
| 628 | 631 |
| 629 | 632 |
| 633 intptr_t ActivationFrame::DeoptId() { |
| 634 if (!token_pos_initialized_) { |
| 635 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
| 636 } |
| 637 return deopt_id_; |
| 638 } |
| 639 |
| 640 |
| 630 intptr_t ActivationFrame::LineNumber() { | 641 intptr_t ActivationFrame::LineNumber() { |
| 631 // Compute line number lazily since it causes scanning of the script. | 642 // Compute line number lazily since it causes scanning of the script. |
| 632 if ((line_number_ < 0) && TokenPos().IsSourcePosition()) { | 643 if ((line_number_ < 0) && TokenPos().IsSourcePosition()) { |
| 633 const TokenPosition token_pos = TokenPos().SourcePosition(); | 644 const TokenPosition token_pos = TokenPos().SourcePosition(); |
| 634 const Script& script = Script::Handle(SourceScript()); | 645 const Script& script = Script::Handle(SourceScript()); |
| 635 script.GetTokenLocation(token_pos, &line_number_, NULL); | 646 script.GetTokenLocation(token_pos, &line_number_, NULL); |
| 636 } | 647 } |
| 637 return line_number_; | 648 return line_number_; |
| 638 } | 649 } |
| 639 | 650 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 bool ActivationFrame::IsDebuggable() const { | 687 bool ActivationFrame::IsDebuggable() const { |
| 677 return Debugger::IsDebuggable(function()); | 688 return Debugger::IsDebuggable(function()); |
| 678 } | 689 } |
| 679 | 690 |
| 680 | 691 |
| 681 // Calculate the context level at the current token index of the frame. | 692 // Calculate the context level at the current token index of the frame. |
| 682 intptr_t ActivationFrame::ContextLevel() { | 693 intptr_t ActivationFrame::ContextLevel() { |
| 683 const Context& ctx = GetSavedCurrentContext(); | 694 const Context& ctx = GetSavedCurrentContext(); |
| 684 if (context_level_ < 0 && !ctx.IsNull()) { | 695 if (context_level_ < 0 && !ctx.IsNull()) { |
| 685 ASSERT(!code_.is_optimized()); | 696 ASSERT(!code_.is_optimized()); |
| 686 context_level_ = 0; | 697 |
| 687 // TODO(hausner): What to do if there is no descriptor entry | 698 intptr_t deopt_id = DeoptId(); |
| 688 // for the code position of the frame? For now say we are at context | 699 if (deopt_id == Thread::kNoDeoptId) { |
| 689 // level 0. | 700 DisassembleToStdout formatter; |
| 690 TokenPos(); | 701 code().Disassemble(&formatter); |
| 691 if (token_pos_ == TokenPosition::kNoSource) { | 702 PcDescriptors::Handle(code().pc_descriptors()).Print(); |
| 692 // No PcDescriptor. | 703 FATAL2("Missing deopt id for pc %" Px " in %s", pc_, |
| 693 return context_level_; | 704 function().ToQualifiedCString()); |
| 694 } | 705 } |
| 695 ASSERT(!pc_desc_.IsNull()); | |
| 696 TokenPosition innermost_begin_pos = TokenPosition::kMinSource; | |
| 697 TokenPosition activation_token_pos = TokenPos().FromSynthetic(); | |
| 698 ASSERT(activation_token_pos.IsReal()); | |
| 699 GetVarDescriptors(); | 706 GetVarDescriptors(); |
| 700 intptr_t var_desc_len = var_descriptors_.Length(); | 707 intptr_t var_desc_len = var_descriptors_.Length(); |
| 708 bool found = false; |
| 701 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 709 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 702 RawLocalVarDescriptors::VarInfo var_info; | 710 RawLocalVarDescriptors::VarInfo var_info; |
| 703 var_descriptors_.GetInfo(cur_idx, &var_info); | 711 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 704 const int8_t kind = var_info.kind(); | 712 const int8_t kind = var_info.kind(); |
| 705 if ((kind == RawLocalVarDescriptors::kContextLevel) && | 713 if ((kind == RawLocalVarDescriptors::kContextLevel) && |
| 706 (var_info.begin_pos <= activation_token_pos) && | 714 (deopt_id >= var_info.begin_pos.value()) && |
| 707 (activation_token_pos < var_info.end_pos)) { | 715 (deopt_id <= var_info.end_pos.value())) { |
| 708 // This var_descriptors_ entry is a context scope which is in scope | 716 context_level_ = var_info.index(); |
| 709 // of the current token position. Now check whether it is shadowing | 717 found = true; |
| 710 // the previous context scope. | 718 break; |
| 711 if (innermost_begin_pos < var_info.begin_pos) { | |
| 712 innermost_begin_pos = var_info.begin_pos; | |
| 713 context_level_ = var_info.index(); | |
| 714 } | |
| 715 } | 719 } |
| 716 } | 720 } |
| 721 if (!found) { |
| 722 DisassembleToStdout formatter; |
| 723 code().Disassemble(&formatter); |
| 724 PcDescriptors::Handle(code().pc_descriptors()).Print(); |
| 725 |
| 726 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, |
| 727 Thread::Current(), |
| 728 StackFrameIterator::kNoCrossThreadIteration); |
| 729 StackFrame* frame = frames.NextFrame(); |
| 730 while (frame != NULL) { |
| 731 OS::PrintErr("%s\n", frame->ToCString()); |
| 732 frame = frames.NextFrame(); |
| 733 } |
| 734 FATAL3("Missing context level for deopt_id=%" Pd ", pc=%" Px " in %s", |
| 735 deopt_id, pc_, function().ToQualifiedCString()); |
| 736 } |
| 717 ASSERT(context_level_ >= 0); | 737 ASSERT(context_level_ >= 0); |
| 718 } | 738 } |
| 719 return context_level_; | 739 return context_level_; |
| 720 } | 740 } |
| 721 | 741 |
| 722 | 742 |
| 723 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { | 743 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { |
| 724 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { | 744 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { |
| 725 return Object::null(); | 745 return Object::null(); |
| 726 } | 746 } |
| (...skipping 3754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4481 | 4501 |
| 4482 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 4502 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 4483 ASSERT(bpt->next() == NULL); | 4503 ASSERT(bpt->next() == NULL); |
| 4484 bpt->set_next(code_breakpoints_); | 4504 bpt->set_next(code_breakpoints_); |
| 4485 code_breakpoints_ = bpt; | 4505 code_breakpoints_ = bpt; |
| 4486 } | 4506 } |
| 4487 | 4507 |
| 4488 #endif // !PRODUCT | 4508 #endif // !PRODUCT |
| 4489 | 4509 |
| 4490 } // namespace dart | 4510 } // namespace dart |
| OLD | NEW |