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 "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 } else { | 453 } else { |
454 column_number_ = -1; | 454 column_number_ = -1; |
455 } | 455 } |
456 } | 456 } |
457 return column_number_; | 457 return column_number_; |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 void ActivationFrame::GetVarDescriptors() { | 461 void ActivationFrame::GetVarDescriptors() { |
462 if (var_descriptors_.IsNull()) { | 462 if (var_descriptors_.IsNull()) { |
463 var_descriptors_ = code().var_descriptors(); | 463 if (code().is_optimized()) { |
| 464 Compiler::EnsureUnoptimizedCode(Thread::Current(), function()); |
| 465 } |
| 466 var_descriptors_ = |
| 467 Code::Handle(function().unoptimized_code()).var_descriptors(); |
464 ASSERT(!var_descriptors_.IsNull()); | 468 ASSERT(!var_descriptors_.IsNull()); |
465 } | 469 } |
466 } | 470 } |
467 | 471 |
468 | 472 |
469 bool ActivationFrame::IsDebuggable() const { | 473 bool ActivationFrame::IsDebuggable() const { |
470 return Debugger::IsDebuggable(function()); | 474 return Debugger::IsDebuggable(function()); |
471 } | 475 } |
472 | 476 |
473 | 477 |
474 // Calculate the context level at the current token index of the frame. | 478 // Calculate the context level at the current token index of the frame. |
475 intptr_t ActivationFrame::ContextLevel() { | 479 intptr_t ActivationFrame::ContextLevel() { |
476 if (context_level_ < 0 && !ctx_.IsNull()) { | 480 const Context& ctx = GetSavedCurrentContext(); |
| 481 if (context_level_ < 0 && !ctx.IsNull()) { |
477 ASSERT(!code_.is_optimized()); | 482 ASSERT(!code_.is_optimized()); |
478 context_level_ = 0; | 483 context_level_ = 0; |
479 // TODO(hausner): What to do if there is no descriptor entry | 484 // TODO(hausner): What to do if there is no descriptor entry |
480 // for the code position of the frame? For now say we are at context | 485 // for the code position of the frame? For now say we are at context |
481 // level 0. | 486 // level 0. |
482 TokenPos(); | 487 TokenPos(); |
483 if (token_pos_ == -1) { | 488 if (token_pos_ == -1) { |
484 // No PcDescriptor. | 489 // No PcDescriptor. |
485 return context_level_; | 490 return context_level_; |
486 } | 491 } |
(...skipping 19 matching lines...) Expand all Loading... |
506 } | 511 } |
507 } | 512 } |
508 } | 513 } |
509 ASSERT(context_level_ >= 0); | 514 ASSERT(context_level_ >= 0); |
510 } | 515 } |
511 return context_level_; | 516 return context_level_; |
512 } | 517 } |
513 | 518 |
514 | 519 |
515 // Get the saved current context of this activation. | 520 // Get the saved current context of this activation. |
516 RawContext* ActivationFrame::GetSavedCurrentContext() { | 521 const Context& ActivationFrame::GetSavedCurrentContext() { |
| 522 if (!ctx_.IsNull()) return ctx_; |
517 GetVarDescriptors(); | 523 GetVarDescriptors(); |
518 intptr_t var_desc_len = var_descriptors_.Length(); | 524 intptr_t var_desc_len = var_descriptors_.Length(); |
519 for (intptr_t i = 0; i < var_desc_len; i++) { | 525 for (intptr_t i = 0; i < var_desc_len; i++) { |
520 RawLocalVarDescriptors::VarInfo var_info; | 526 RawLocalVarDescriptors::VarInfo var_info; |
521 var_descriptors_.GetInfo(i, &var_info); | 527 var_descriptors_.GetInfo(i, &var_info); |
522 const int8_t kind = var_info.kind(); | 528 const int8_t kind = var_info.kind(); |
523 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 529 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
524 if (FLAG_trace_debugger_stacktrace) { | 530 if (FLAG_trace_debugger_stacktrace) { |
525 OS::PrintErr("\tFound saved current ctx at index %d\n", | 531 OS::PrintErr("\tFound saved current ctx at index %d\n", |
526 var_info.index()); | 532 var_info.index()); |
527 } | 533 } |
528 ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext()); | 534 ctx_ ^= GetLocalVar(var_info.index()); |
529 return Context::RawCast(GetLocalVar(var_info.index())); | 535 return ctx_; |
530 } | 536 } |
531 } | 537 } |
532 UNREACHABLE(); | 538 UNREACHABLE(); |
533 return Context::null(); | 539 return Context::ZoneHandle(Context::null()); |
534 } | 540 } |
535 | 541 |
536 | 542 |
537 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 543 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
538 const Instance& exc_obj) const { | 544 const Instance& exc_obj) const { |
539 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 545 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
540 Array& handled_types = Array::Handle(); | 546 Array& handled_types = Array::Handle(); |
541 AbstractType& type = Type::Handle(); | 547 AbstractType& type = Type::Handle(); |
542 const TypeArguments& no_instantiator = TypeArguments::Handle(); | 548 const TypeArguments& no_instantiator = TypeArguments::Handle(); |
543 for (intptr_t frame_index = 0; | 549 for (intptr_t frame_index = 0; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 653 } |
648 vars_initialized_ = true; | 654 vars_initialized_ = true; |
649 } | 655 } |
650 | 656 |
651 | 657 |
652 intptr_t ActivationFrame::NumLocalVariables() { | 658 intptr_t ActivationFrame::NumLocalVariables() { |
653 GetDescIndices(); | 659 GetDescIndices(); |
654 return desc_indices_.length(); | 660 return desc_indices_.length(); |
655 } | 661 } |
656 | 662 |
657 // TODO(hausner): Handle captured variables. | 663 |
658 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { | 664 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { |
659 if (deopt_frame_.IsNull()) { | 665 if (deopt_frame_.IsNull()) { |
660 uword var_address = fp() + slot_index * kWordSize; | 666 uword var_address = fp() + slot_index * kWordSize; |
661 return reinterpret_cast<RawObject*>( | 667 return reinterpret_cast<RawObject*>( |
662 *reinterpret_cast<uword*>(var_address)); | 668 *reinterpret_cast<uword*>(var_address)); |
663 } else { | 669 } else { |
664 return deopt_frame_.At(deopt_frame_offset_ + slot_index); | 670 return deopt_frame_.At(deopt_frame_offset_ + slot_index); |
665 } | 671 } |
666 } | 672 } |
667 | 673 |
(...skipping 20 matching lines...) Expand all Loading... |
688 ctx_slot, | 694 ctx_slot, |
689 frame_ctx_level, | 695 frame_ctx_level, |
690 var_ctx_level); | 696 var_ctx_level); |
691 | 697 |
692 OS::PrintErr("-------------------------\n" | 698 OS::PrintErr("-------------------------\n" |
693 "Current frame:\n%s\n", | 699 "Current frame:\n%s\n", |
694 this->ToCString()); | 700 this->ToCString()); |
695 | 701 |
696 OS::PrintErr("-------------------------\n" | 702 OS::PrintErr("-------------------------\n" |
697 "Context contents:\n"); | 703 "Context contents:\n"); |
698 ctx_.Dump(8); | 704 const Context& ctx = GetSavedCurrentContext(); |
| 705 ctx.Dump(8); |
699 | 706 |
700 OS::PrintErr("-------------------------\n" | 707 OS::PrintErr("-------------------------\n" |
701 "Debugger stack trace...\n\n"); | 708 "Debugger stack trace...\n\n"); |
702 DebuggerStackTrace* stack = | 709 DebuggerStackTrace* stack = |
703 Isolate::Current()->debugger()->StackTrace(); | 710 Isolate::Current()->debugger()->StackTrace(); |
704 intptr_t num_frames = stack->Length(); | 711 intptr_t num_frames = stack->Length(); |
705 for (intptr_t i = 0; i < num_frames; i++) { | 712 for (intptr_t i = 0; i < num_frames; i++) { |
706 ActivationFrame* frame = stack->FrameAt(i); | 713 ActivationFrame* frame = stack->FrameAt(i); |
707 OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); | 714 OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); |
708 } | 715 } |
(...skipping 28 matching lines...) Expand all Loading... |
737 ASSERT(token_pos != NULL); | 744 ASSERT(token_pos != NULL); |
738 *token_pos = var_info.begin_pos; | 745 *token_pos = var_info.begin_pos; |
739 ASSERT(end_pos != NULL); | 746 ASSERT(end_pos != NULL); |
740 *end_pos = var_info.end_pos; | 747 *end_pos = var_info.end_pos; |
741 ASSERT(value != NULL); | 748 ASSERT(value != NULL); |
742 const int8_t kind = var_info.kind(); | 749 const int8_t kind = var_info.kind(); |
743 if (kind == RawLocalVarDescriptors::kStackVar) { | 750 if (kind == RawLocalVarDescriptors::kStackVar) { |
744 *value = GetLocalInstanceVar(var_info.index()); | 751 *value = GetLocalInstanceVar(var_info.index()); |
745 } else { | 752 } else { |
746 ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 753 ASSERT(kind == RawLocalVarDescriptors::kContextVar); |
747 ASSERT(!ctx_.IsNull()); | 754 const Context& ctx = GetSavedCurrentContext(); |
| 755 ASSERT(!ctx.IsNull()); |
748 | 756 |
749 // The context level at the PC/token index of this activation frame. | 757 // The context level at the PC/token index of this activation frame. |
750 intptr_t frame_ctx_level = ContextLevel(); | 758 intptr_t frame_ctx_level = ContextLevel(); |
751 | 759 |
752 // The context level of the variable. | 760 // The context level of the variable. |
753 intptr_t var_ctx_level = var_info.scope_id; | 761 intptr_t var_ctx_level = var_info.scope_id; |
754 intptr_t level_diff = frame_ctx_level - var_ctx_level; | 762 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
755 intptr_t ctx_slot = var_info.index(); | 763 intptr_t ctx_slot = var_info.index(); |
756 if (level_diff == 0) { | 764 if (level_diff == 0) { |
757 if ((ctx_slot < 0) || | 765 if ((ctx_slot < 0) || |
758 (ctx_slot >= ctx_.num_variables())) { | 766 (ctx_slot >= ctx.num_variables())) { |
759 PrintContextMismatchError(*name, ctx_slot, | 767 PrintContextMismatchError(*name, ctx_slot, |
760 frame_ctx_level, var_ctx_level); | 768 frame_ctx_level, var_ctx_level); |
761 } | 769 } |
762 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); | 770 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables())); |
763 *value = ctx_.At(ctx_slot); | 771 *value = ctx.At(ctx_slot); |
764 } else { | 772 } else { |
765 ASSERT(level_diff > 0); | 773 ASSERT(level_diff > 0); |
766 Context& var_ctx = Context::Handle(ctx_.raw()); | 774 Context& var_ctx = Context::Handle(ctx.raw()); |
767 while (level_diff > 0 && !var_ctx.IsNull()) { | 775 while (level_diff > 0 && !var_ctx.IsNull()) { |
768 level_diff--; | 776 level_diff--; |
769 var_ctx = var_ctx.parent(); | 777 var_ctx = var_ctx.parent(); |
770 } | 778 } |
771 if (var_ctx.IsNull() || | 779 if (var_ctx.IsNull() || |
772 (ctx_slot < 0) || | 780 (ctx_slot < 0) || |
773 (ctx_slot >= var_ctx.num_variables())) { | 781 (ctx_slot >= var_ctx.num_variables())) { |
774 PrintContextMismatchError(*name, ctx_slot, | 782 PrintContextMismatchError(*name, ctx_slot, |
775 frame_ctx_level, var_ctx_level); | 783 frame_ctx_level, var_ctx_level); |
776 } | 784 } |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, | 1186 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, |
1179 uword pc, | 1187 uword pc, |
1180 StackFrame* frame, | 1188 StackFrame* frame, |
1181 const Code& code, | 1189 const Code& code, |
1182 const Array& deopt_frame, | 1190 const Array& deopt_frame, |
1183 intptr_t deopt_frame_offset) { | 1191 intptr_t deopt_frame_offset) { |
1184 ASSERT(code.ContainsInstructionAt(pc)); | 1192 ASSERT(code.ContainsInstructionAt(pc)); |
1185 ActivationFrame* activation = | 1193 ActivationFrame* activation = |
1186 new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 1194 new ActivationFrame(pc, frame->fp(), frame->sp(), code, |
1187 deopt_frame, deopt_frame_offset); | 1195 deopt_frame, deopt_frame_offset); |
1188 | |
1189 // Recover the context for this frame. | |
1190 const Context& ctx = | |
1191 Context::Handle(isolate, activation->GetSavedCurrentContext()); | |
1192 ASSERT(!ctx.IsNull()); | |
1193 activation->SetContext(ctx); | |
1194 if (FLAG_trace_debugger_stacktrace) { | 1196 if (FLAG_trace_debugger_stacktrace) { |
| 1197 const Context& ctx = activation->GetSavedCurrentContext(); |
1195 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); | 1198 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); |
1196 } | 1199 } |
1197 if (FLAG_trace_debugger_stacktrace) { | 1200 if (FLAG_trace_debugger_stacktrace) { |
1198 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); | 1201 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); |
1199 } | 1202 } |
1200 return activation; | 1203 return activation; |
1201 } | 1204 } |
1202 | 1205 |
1203 | 1206 |
1204 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1207 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, |
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 } | 2639 } |
2637 | 2640 |
2638 | 2641 |
2639 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2642 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
2640 ASSERT(bpt->next() == NULL); | 2643 ASSERT(bpt->next() == NULL); |
2641 bpt->set_next(code_breakpoints_); | 2644 bpt->set_next(code_breakpoints_); |
2642 code_breakpoints_ = bpt; | 2645 code_breakpoints_ = bpt; |
2643 } | 2646 } |
2644 | 2647 |
2645 } // namespace dart | 2648 } // namespace dart |
OLD | NEW |