| 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 |