Index: runtime/vm/debugger_x64.cc |
=================================================================== |
--- runtime/vm/debugger_x64.cc (revision 31811) |
+++ runtime/vm/debugger_x64.cc (working copy) |
@@ -8,7 +8,9 @@ |
#include "vm/debugger.h" |
#include "vm/assembler.h" |
+#include "vm/code_patcher.h" |
#include "vm/cpu.h" |
+#include "vm/instructions.h" |
#include "vm/stub_code.h" |
namespace dart { |
@@ -32,6 +34,80 @@ |
*reinterpret_cast<uword*>(closure_addr)); |
} |
+ |
+uword CodeBreakpoint::OrigStubAddress() const { |
+ const Code& code = |
+ Code::Handle(Function::Handle(function_).unoptimized_code()); |
+ const Array& object_pool = Array::Handle(code.ObjectPool()); |
+ uword offset = saved_value_ + kHeapObjectTag; |
+ ASSERT((offset % kWordSize) == 0); |
+ const intptr_t index = (offset - Array::data_offset()) / kWordSize; |
+ const uword stub_address = reinterpret_cast<uword>(object_pool.At(index)); |
+ ASSERT(stub_address % kWordSize == 0); |
+ return stub_address; |
+} |
+ |
+ |
+void CodeBreakpoint::PatchCode() { |
+ ASSERT(!is_enabled_); |
+ switch (breakpoint_kind_) { |
+ case PcDescriptors::kIcCall: { |
+ int32_t offset = CodePatcher::GetPoolOffsetAt(pc_); |
+ ASSERT((offset > 0) && ((offset % 8) == 7)); |
+ saved_value_ = static_cast<uword>(offset); |
+ const int32_t stub_offset = |
+ InstructionPattern::OffsetFromPPIndex( |
+ Assembler::kBreakpointDynamicCPIndex); |
+ CodePatcher::SetPoolOffsetAt(pc_, stub_offset); |
+ break; |
+ } |
+ case PcDescriptors::kUnoptStaticCall: { |
+ int32_t offset = CodePatcher::GetPoolOffsetAt(pc_); |
+ ASSERT((offset > 0) && ((offset % 8) == 7)); |
+ saved_value_ = static_cast<uword>(offset); |
+ const uint32_t stub_offset = |
+ InstructionPattern::OffsetFromPPIndex( |
+ Assembler::kBreakpointStaticCPIndex); |
+ CodePatcher::SetPoolOffsetAt(pc_, stub_offset); |
+ break; |
+ } |
+ case PcDescriptors::kRuntimeCall: |
+ case PcDescriptors::kClosureCall: |
+ case PcDescriptors::kReturn: { |
+ int32_t offset = CodePatcher::GetPoolOffsetAt(pc_); |
+ ASSERT((offset > 0) && ((offset % 8) == 7)); |
+ saved_value_ = static_cast<uword>(offset); |
+ const uint32_t stub_offset = |
+ InstructionPattern::OffsetFromPPIndex( |
+ Assembler::kBreakpointRuntimeCPIndex); |
+ CodePatcher::SetPoolOffsetAt(pc_, stub_offset); |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+ is_enabled_ = true; |
+} |
+ |
+ |
+void CodeBreakpoint::RestoreCode() { |
+ ASSERT(is_enabled_); |
+ switch (breakpoint_kind_) { |
+ case PcDescriptors::kIcCall: |
+ case PcDescriptors::kUnoptStaticCall: |
+ case PcDescriptors::kClosureCall: |
+ case PcDescriptors::kRuntimeCall: |
+ case PcDescriptors::kReturn: { |
+ CodePatcher::SetPoolOffsetAt(pc_, static_cast<int32_t>(saved_value_)); |
+ break; |
+ } |
+ default: |
+ UNREACHABLE(); |
+ } |
+ is_enabled_ = false; |
+} |
+ |
+ |
} // namespace dart |
#endif // defined TARGET_ARCH_X64 |