| 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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 } | 550 } |
| 551 | 551 |
| 552 | 552 |
| 553 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { | 553 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { |
| 554 trace_.Add(frame); | 554 trace_.Add(frame); |
| 555 } | 555 } |
| 556 | 556 |
| 557 | 557 |
| 558 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) | 558 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) |
| 559 : function_(func.raw()), | 559 : function_(func.raw()), |
| 560 code_(Code::ZoneHandle(func.unoptimized_code())), |
| 560 pc_desc_index_(pc_desc_index), | 561 pc_desc_index_(pc_desc_index), |
| 561 pc_(0), | 562 pc_(0), |
| 562 line_number_(-1), | 563 line_number_(-1), |
| 563 is_enabled_(false), | 564 is_enabled_(false), |
| 564 src_bpt_(NULL), | 565 src_bpt_(NULL), |
| 565 next_(NULL) { | 566 next_(NULL) { |
| 566 ASSERT(!func.HasOptimizedCode()); | 567 ASSERT(!func.HasOptimizedCode()); |
| 567 Code& code = Code::Handle(func.unoptimized_code()); | 568 ASSERT(!code_.IsNull()); // Function must be compiled. |
| 568 ASSERT(!code.IsNull()); // Function must be compiled. | 569 PcDescriptors& desc = PcDescriptors::Handle(code_.pc_descriptors()); |
| 569 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | |
| 570 ASSERT(pc_desc_index < desc.Length()); | 570 ASSERT(pc_desc_index < desc.Length()); |
| 571 token_pos_ = desc.TokenPos(pc_desc_index); | 571 token_pos_ = desc.TokenPos(pc_desc_index); |
| 572 ASSERT(token_pos_ >= 0); | 572 ASSERT(token_pos_ >= 0); |
| 573 pc_ = desc.PC(pc_desc_index); | 573 pc_ = desc.PC(pc_desc_index); |
| 574 ASSERT(pc_ != 0); | 574 ASSERT(pc_ != 0); |
| 575 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 575 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
| 576 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || | 576 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || |
| 577 (breakpoint_kind_ == PcDescriptors::kFuncCall) || | 577 (breakpoint_kind_ == PcDescriptors::kFuncCall) || |
| 578 (breakpoint_kind_ == PcDescriptors::kReturn)); | 578 (breakpoint_kind_ == PcDescriptors::kReturn)); |
| 579 } | 579 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 } | 614 } |
| 615 return line_number_; | 615 return line_number_; |
| 616 } | 616 } |
| 617 | 617 |
| 618 | 618 |
| 619 void CodeBreakpoint::PatchCode() { | 619 void CodeBreakpoint::PatchCode() { |
| 620 ASSERT(!is_enabled_); | 620 ASSERT(!is_enabled_); |
| 621 switch (breakpoint_kind_) { | 621 switch (breakpoint_kind_) { |
| 622 case PcDescriptors::kIcCall: { | 622 case PcDescriptors::kIcCall: { |
| 623 saved_bytes_.target_address_ = | 623 saved_bytes_.target_address_ = |
| 624 CodePatcher::GetInstanceCallAt(pc_, NULL, NULL); | 624 CodePatcher::GetInstanceCallAt(pc_, code_, NULL, NULL); |
| 625 CodePatcher::PatchInstanceCallAt(pc_, | 625 CodePatcher::PatchInstanceCallAt(pc_, code_, |
| 626 StubCode::BreakpointDynamicEntryPoint()); | 626 StubCode::BreakpointDynamicEntryPoint()); |
| 627 break; | 627 break; |
| 628 } | 628 } |
| 629 case PcDescriptors::kFuncCall: { | 629 case PcDescriptors::kFuncCall: { |
| 630 saved_bytes_.target_address_ = CodePatcher::GetStaticCallTargetAt(pc_); | 630 saved_bytes_.target_address_ = |
| 631 CodePatcher::PatchStaticCallAt(pc_, | 631 CodePatcher::GetStaticCallTargetAt(pc_, code_); |
| 632 StubCode::BreakpointStaticEntryPoint()); | 632 CodePatcher::PatchStaticCallAt(pc_, code_, |
| 633 StubCode::BreakpointStaticEntryPoint()); |
| 633 break; | 634 break; |
| 634 } | 635 } |
| 635 case PcDescriptors::kReturn: | 636 case PcDescriptors::kReturn: |
| 636 PatchFunctionReturn(); | 637 PatchFunctionReturn(); |
| 637 break; | 638 break; |
| 638 default: | 639 default: |
| 639 UNREACHABLE(); | 640 UNREACHABLE(); |
| 640 } | 641 } |
| 641 is_enabled_ = true; | 642 is_enabled_ = true; |
| 642 } | 643 } |
| 643 | 644 |
| 644 | 645 |
| 645 void CodeBreakpoint::RestoreCode() { | 646 void CodeBreakpoint::RestoreCode() { |
| 646 ASSERT(is_enabled_); | 647 ASSERT(is_enabled_); |
| 647 switch (breakpoint_kind_) { | 648 switch (breakpoint_kind_) { |
| 648 case PcDescriptors::kIcCall: | 649 case PcDescriptors::kIcCall: |
| 649 CodePatcher::PatchInstanceCallAt(pc_, saved_bytes_.target_address_); | 650 CodePatcher::PatchInstanceCallAt(pc_, code_, |
| 651 saved_bytes_.target_address_); |
| 650 break; | 652 break; |
| 651 case PcDescriptors::kFuncCall: | 653 case PcDescriptors::kFuncCall: |
| 652 CodePatcher::PatchStaticCallAt(pc_, saved_bytes_.target_address_); | 654 CodePatcher::PatchStaticCallAt(pc_, code_, |
| 655 saved_bytes_.target_address_); |
| 653 break; | 656 break; |
| 654 case PcDescriptors::kReturn: | 657 case PcDescriptors::kReturn: |
| 655 RestoreFunctionReturn(); | 658 RestoreFunctionReturn(); |
| 656 break; | 659 break; |
| 657 default: | 660 default: |
| 658 UNREACHABLE(); | 661 UNREACHABLE(); |
| 659 } | 662 } |
| 660 is_enabled_ = false; | 663 is_enabled_ = false; |
| 661 } | 664 } |
| 662 | 665 |
| (...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 func_to_instrument = caller_frame->function().raw(); | 1479 func_to_instrument = caller_frame->function().raw(); |
| 1477 } | 1480 } |
| 1478 } | 1481 } |
| 1479 } else if (resume_action_ == kStepInto) { | 1482 } else if (resume_action_ == kStepInto) { |
| 1480 // If the call target is not debuggable, we treat StepInto like | 1483 // If the call target is not debuggable, we treat StepInto like |
| 1481 // a StepOver, that is we instrument the current function. | 1484 // a StepOver, that is we instrument the current function. |
| 1482 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) { | 1485 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) { |
| 1483 func_to_instrument = bpt->function(); | 1486 func_to_instrument = bpt->function(); |
| 1484 ICData& ic_data = ICData::Handle(); | 1487 ICData& ic_data = ICData::Handle(); |
| 1485 Array& descriptor = Array::Handle(); | 1488 Array& descriptor = Array::Handle(); |
| 1486 CodePatcher::GetInstanceCallAt(bpt->pc_, &ic_data, &descriptor); | 1489 CodePatcher::GetInstanceCallAt(bpt->pc_, bpt->code_, |
| 1490 &ic_data, &descriptor); |
| 1487 ArgumentsDescriptor arg_descriptor(descriptor); | 1491 ArgumentsDescriptor arg_descriptor(descriptor); |
| 1488 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); | 1492 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); |
| 1489 intptr_t num_args = arg_descriptor.Count(); | 1493 intptr_t num_args = arg_descriptor.Count(); |
| 1490 Instance& receiver = | 1494 Instance& receiver = |
| 1491 Instance::Handle(top_frame->GetInstanceCallReceiver(num_args)); | 1495 Instance::Handle(top_frame->GetInstanceCallReceiver(num_args)); |
| 1492 Code& code = | 1496 Code& code = |
| 1493 Code::Handle(ResolveCompileInstanceCallTarget(receiver, | 1497 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
| 1494 ic_data, | 1498 ic_data, |
| 1495 descriptor)); | 1499 descriptor)); |
| 1496 if (!code.IsNull()) { | 1500 if (!code.IsNull()) { |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 } | 1719 } |
| 1716 | 1720 |
| 1717 | 1721 |
| 1718 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1722 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1719 ASSERT(bpt->next() == NULL); | 1723 ASSERT(bpt->next() == NULL); |
| 1720 bpt->set_next(code_breakpoints_); | 1724 bpt->set_next(code_breakpoints_); |
| 1721 code_breakpoints_ = bpt; | 1725 code_breakpoints_ = bpt; |
| 1722 } | 1726 } |
| 1723 | 1727 |
| 1724 } // namespace dart | 1728 } // namespace dart |
| OLD | NEW |