| 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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 script.GetTokenLocation(token_pos_, &line_number_, &ignore_column); | 613 script.GetTokenLocation(token_pos_, &line_number_, &ignore_column); |
| 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 const Code& code = |
| 624 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 623 saved_bytes_.target_address_ = | 625 saved_bytes_.target_address_ = |
| 624 CodePatcher::GetInstanceCallAt(pc_, NULL, NULL); | 626 CodePatcher::GetInstanceCallAt(pc_, code, NULL, NULL); |
| 625 CodePatcher::PatchInstanceCallAt(pc_, | 627 CodePatcher::PatchInstanceCallAt(pc_, code, |
| 626 StubCode::BreakpointDynamicEntryPoint()); | 628 StubCode::BreakpointDynamicEntryPoint()); |
| 627 break; | 629 break; |
| 628 } | 630 } |
| 629 case PcDescriptors::kFuncCall: { | 631 case PcDescriptors::kFuncCall: { |
| 630 saved_bytes_.target_address_ = CodePatcher::GetStaticCallTargetAt(pc_); | 632 const Code& code = |
| 631 CodePatcher::PatchStaticCallAt(pc_, | 633 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 632 StubCode::BreakpointStaticEntryPoint()); | 634 saved_bytes_.target_address_ = |
| 635 CodePatcher::GetStaticCallTargetAt(pc_, code); |
| 636 CodePatcher::PatchStaticCallAt(pc_, code, |
| 637 StubCode::BreakpointStaticEntryPoint()); |
| 633 break; | 638 break; |
| 634 } | 639 } |
| 635 case PcDescriptors::kReturn: | 640 case PcDescriptors::kReturn: |
| 636 PatchFunctionReturn(); | 641 PatchFunctionReturn(); |
| 637 break; | 642 break; |
| 638 default: | 643 default: |
| 639 UNREACHABLE(); | 644 UNREACHABLE(); |
| 640 } | 645 } |
| 641 is_enabled_ = true; | 646 is_enabled_ = true; |
| 642 } | 647 } |
| 643 | 648 |
| 644 | 649 |
| 645 void CodeBreakpoint::RestoreCode() { | 650 void CodeBreakpoint::RestoreCode() { |
| 646 ASSERT(is_enabled_); | 651 ASSERT(is_enabled_); |
| 647 switch (breakpoint_kind_) { | 652 switch (breakpoint_kind_) { |
| 648 case PcDescriptors::kIcCall: | 653 case PcDescriptors::kIcCall: { |
| 649 CodePatcher::PatchInstanceCallAt(pc_, saved_bytes_.target_address_); | 654 const Code& code = |
| 655 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 656 CodePatcher::PatchInstanceCallAt(pc_, code, |
| 657 saved_bytes_.target_address_); |
| 650 break; | 658 break; |
| 651 case PcDescriptors::kFuncCall: | 659 } |
| 652 CodePatcher::PatchStaticCallAt(pc_, saved_bytes_.target_address_); | 660 case PcDescriptors::kFuncCall: { |
| 661 const Code& code = |
| 662 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 663 CodePatcher::PatchStaticCallAt(pc_, code, |
| 664 saved_bytes_.target_address_); |
| 653 break; | 665 break; |
| 666 } |
| 654 case PcDescriptors::kReturn: | 667 case PcDescriptors::kReturn: |
| 655 RestoreFunctionReturn(); | 668 RestoreFunctionReturn(); |
| 656 break; | 669 break; |
| 657 default: | 670 default: |
| 658 UNREACHABLE(); | 671 UNREACHABLE(); |
| 659 } | 672 } |
| 660 is_enabled_ = false; | 673 is_enabled_ = false; |
| 661 } | 674 } |
| 662 | 675 |
| 663 | 676 |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 func_to_instrument = caller_frame->function().raw(); | 1489 func_to_instrument = caller_frame->function().raw(); |
| 1477 } | 1490 } |
| 1478 } | 1491 } |
| 1479 } else if (resume_action_ == kStepInto) { | 1492 } else if (resume_action_ == kStepInto) { |
| 1480 // If the call target is not debuggable, we treat StepInto like | 1493 // If the call target is not debuggable, we treat StepInto like |
| 1481 // a StepOver, that is we instrument the current function. | 1494 // a StepOver, that is we instrument the current function. |
| 1482 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) { | 1495 if (bpt->breakpoint_kind_ == PcDescriptors::kIcCall) { |
| 1483 func_to_instrument = bpt->function(); | 1496 func_to_instrument = bpt->function(); |
| 1484 ICData& ic_data = ICData::Handle(); | 1497 ICData& ic_data = ICData::Handle(); |
| 1485 Array& descriptor = Array::Handle(); | 1498 Array& descriptor = Array::Handle(); |
| 1486 CodePatcher::GetInstanceCallAt(bpt->pc_, &ic_data, &descriptor); | 1499 const Code& code = |
| 1500 Code::Handle(Function::Handle(bpt->function_).unoptimized_code()); |
| 1501 CodePatcher::GetInstanceCallAt(bpt->pc_, code, &ic_data, &descriptor); |
| 1487 ArgumentsDescriptor arg_descriptor(descriptor); | 1502 ArgumentsDescriptor arg_descriptor(descriptor); |
| 1488 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); | 1503 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); |
| 1489 intptr_t num_args = arg_descriptor.Count(); | 1504 intptr_t num_args = arg_descriptor.Count(); |
| 1490 Instance& receiver = | 1505 Instance& receiver = |
| 1491 Instance::Handle(top_frame->GetInstanceCallReceiver(num_args)); | 1506 Instance::Handle(top_frame->GetInstanceCallReceiver(num_args)); |
| 1492 Code& code = | 1507 Code& target_code = |
| 1493 Code::Handle(ResolveCompileInstanceCallTarget(receiver, | 1508 Code::Handle(ResolveCompileInstanceCallTarget(receiver, |
| 1494 ic_data, | 1509 ic_data, |
| 1495 descriptor)); | 1510 descriptor)); |
| 1496 if (!code.IsNull()) { | 1511 if (!target_code.IsNull()) { |
| 1497 Function& callee = Function::Handle(code.function()); | 1512 Function& callee = Function::Handle(target_code.function()); |
| 1498 if (IsDebuggable(callee)) { | 1513 if (IsDebuggable(callee)) { |
| 1499 func_to_instrument = callee.raw(); | 1514 func_to_instrument = callee.raw(); |
| 1500 } | 1515 } |
| 1501 } | 1516 } |
| 1502 } else if (bpt->breakpoint_kind_ == PcDescriptors::kFuncCall) { | 1517 } else if (bpt->breakpoint_kind_ == PcDescriptors::kFuncCall) { |
| 1503 func_to_instrument = bpt->function(); | 1518 func_to_instrument = bpt->function(); |
| 1504 const Code& code = Code::Handle(func_to_instrument.CurrentCode()); | 1519 const Code& code = Code::Handle(func_to_instrument.CurrentCode()); |
| 1505 const Function& callee = | 1520 const Function& callee = |
| 1506 Function::Handle(code.GetStaticCallTargetFunctionAt(bpt->pc_)); | 1521 Function::Handle(code.GetStaticCallTargetFunctionAt(bpt->pc_)); |
| 1507 ASSERT(!callee.IsNull()); | 1522 ASSERT(!callee.IsNull()); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 } | 1730 } |
| 1716 | 1731 |
| 1717 | 1732 |
| 1718 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1733 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1719 ASSERT(bpt->next() == NULL); | 1734 ASSERT(bpt->next() == NULL); |
| 1720 bpt->set_next(code_breakpoints_); | 1735 bpt->set_next(code_breakpoints_); |
| 1721 code_breakpoints_ = bpt; | 1736 code_breakpoints_ = bpt; |
| 1722 } | 1737 } |
| 1723 | 1738 |
| 1724 } // namespace dart | 1739 } // namespace dart |
| OLD | NEW |