Index: runtime/vm/debugger_arm64.cc |
=================================================================== |
--- runtime/vm/debugger_arm64.cc (revision 35975) |
+++ runtime/vm/debugger_arm64.cc (working copy) |
@@ -15,30 +15,85 @@ |
RawInstance* ActivationFrame::GetInstanceCallReceiver( |
intptr_t num_actual_args) { |
- UNIMPLEMENTED(); |
- return NULL; |
+ ASSERT(num_actual_args > 0); // At minimum we have a receiver on the stack. |
+ // Stack pointer points to last argument that was pushed on the stack. |
+ const uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize); |
+ const uword receiver = *reinterpret_cast<uword*>(receiver_addr); |
+ return reinterpret_cast<RawInstance*>(receiver); |
} |
RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) { |
- UNIMPLEMENTED(); |
- return NULL; |
+ // At a minimum we have the closure object on the stack. |
+ ASSERT(num_actual_args > 0); |
+ // Stack pointer points to last argument that was pushed on the stack. |
+ const uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize); |
+ const uword closure = *reinterpret_cast<uword*>(closure_addr); |
+ return reinterpret_cast<RawObject*>(closure); |
} |
uword CodeBreakpoint::OrigStubAddress() const { |
- UNIMPLEMENTED(); |
- return 0; |
+ const Code& code = Code::Handle(code_); |
+ const Array& object_pool = Array::Handle(code.ObjectPool()); |
+ const uword offset = saved_value_; |
+ 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() { |
- UNIMPLEMENTED(); |
+ ASSERT(!is_enabled_); |
+ const Code& code = Code::Handle(code_); |
+ const Instructions& instrs = Instructions::Handle(code.instructions()); |
+ { |
+ WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); |
+ switch (breakpoint_kind_) { |
+ case PcDescriptors::kIcCall: |
+ case PcDescriptors::kUnoptStaticCall: |
+ case PcDescriptors::kRuntimeCall: |
+ case PcDescriptors::kClosureCall: |
+ case PcDescriptors::kReturn: { |
+ int32_t offset = CodePatcher::GetPoolOffsetAt(pc_); |
+ ASSERT((offset > 0) && ((offset & 0x7) == 0)); |
+ 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() { |
- UNIMPLEMENTED(); |
+ ASSERT(is_enabled_); |
+ const Code& code = Code::Handle(code_); |
+ const Instructions& instrs = Instructions::Handle(code.instructions()); |
+ { |
+ WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); |
+ 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 |