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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 ASSERT(!var_descriptors_.IsNull()); | 682 ASSERT(!var_descriptors_.IsNull()); |
672 } | 683 } |
673 } | 684 } |
674 | 685 |
675 | 686 |
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 |
| 692 void ActivationFrame::PrintDescriptorsError(const char* message) { |
| 693 OS::PrintErr("Bad descriptors: %s\n", message); |
| 694 OS::PrintErr("function %s\n", function().ToQualifiedCString()); |
| 695 OS::PrintErr("pc_ %" Px "\n", pc_); |
| 696 OS::PrintErr("deopt_id_ %" Px "\n", deopt_id_); |
| 697 OS::PrintErr("context_level_ %" Px "\n", context_level_); |
| 698 DisassembleToStdout formatter; |
| 699 code().Disassemble(&formatter); |
| 700 PcDescriptors::Handle(code().pc_descriptors()).Print(); |
| 701 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, |
| 702 Thread::Current(), |
| 703 StackFrameIterator::kNoCrossThreadIteration); |
| 704 StackFrame* frame = frames.NextFrame(); |
| 705 while (frame != NULL) { |
| 706 OS::PrintErr("%s\n", frame->ToCString()); |
| 707 frame = frames.NextFrame(); |
| 708 } |
| 709 OS::Abort(); |
| 710 } |
| 711 |
| 712 |
681 // Calculate the context level at the current token index of the frame. | 713 // Calculate the context level at the current token index of the frame. |
682 intptr_t ActivationFrame::ContextLevel() { | 714 intptr_t ActivationFrame::ContextLevel() { |
683 const Context& ctx = GetSavedCurrentContext(); | 715 const Context& ctx = GetSavedCurrentContext(); |
684 if (context_level_ < 0 && !ctx.IsNull()) { | 716 if (context_level_ < 0 && !ctx.IsNull()) { |
685 ASSERT(!code_.is_optimized()); | 717 ASSERT(!code_.is_optimized()); |
686 context_level_ = 0; | 718 |
687 // TODO(hausner): What to do if there is no descriptor entry | 719 GetVarDescriptors(); |
688 // for the code position of the frame? For now say we are at context | 720 intptr_t deopt_id = DeoptId(); |
689 // level 0. | 721 if (deopt_id == Thread::kNoDeoptId) { |
690 TokenPos(); | 722 PrintDescriptorsError("Missing deopt id"); |
691 if (token_pos_ == TokenPosition::kNoSource) { | |
692 // No PcDescriptor. | |
693 return context_level_; | |
694 } | 723 } |
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(); | |
700 intptr_t var_desc_len = var_descriptors_.Length(); | 724 intptr_t var_desc_len = var_descriptors_.Length(); |
| 725 bool found = false; |
701 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 726 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
702 RawLocalVarDescriptors::VarInfo var_info; | 727 RawLocalVarDescriptors::VarInfo var_info; |
703 var_descriptors_.GetInfo(cur_idx, &var_info); | 728 var_descriptors_.GetInfo(cur_idx, &var_info); |
704 const int8_t kind = var_info.kind(); | 729 const int8_t kind = var_info.kind(); |
705 if ((kind == RawLocalVarDescriptors::kContextLevel) && | 730 if ((kind == RawLocalVarDescriptors::kContextLevel) && |
706 (var_info.begin_pos <= activation_token_pos) && | 731 (deopt_id >= var_info.begin_pos.value()) && |
707 (activation_token_pos < var_info.end_pos)) { | 732 (deopt_id <= var_info.end_pos.value())) { |
708 // This var_descriptors_ entry is a context scope which is in scope | 733 context_level_ = var_info.index(); |
709 // of the current token position. Now check whether it is shadowing | 734 found = true; |
710 // the previous context scope. | 735 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 } | 736 } |
716 } | 737 } |
| 738 if (!found) { |
| 739 PrintDescriptorsError("Missing context level"); |
| 740 } |
717 ASSERT(context_level_ >= 0); | 741 ASSERT(context_level_ >= 0); |
718 } | 742 } |
719 return context_level_; | 743 return context_level_; |
720 } | 744 } |
721 | 745 |
722 | 746 |
723 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { | 747 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { |
724 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { | 748 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { |
725 return Object::null(); | 749 return Object::null(); |
726 } | 750 } |
(...skipping 3754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4481 | 4505 |
4482 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 4506 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
4483 ASSERT(bpt->next() == NULL); | 4507 ASSERT(bpt->next() == NULL); |
4484 bpt->set_next(code_breakpoints_); | 4508 bpt->set_next(code_breakpoints_); |
4485 code_breakpoints_ = bpt; | 4509 code_breakpoints_ = bpt; |
4486 } | 4510 } |
4487 | 4511 |
4488 #endif // !PRODUCT | 4512 #endif // !PRODUCT |
4489 | 4513 |
4490 } // namespace dart | 4514 } // namespace dart |
OLD | NEW |