diff options
author | Jason Molenda <jmolenda@apple.com> | 2016-01-08 21:40:11 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2016-01-08 21:40:11 +0000 |
commit | fd4cea53d585904c58aef9c35b4a14f755bb30a9 (patch) | |
tree | cbc7308d16a75cc459d0f84510c21cb1cf80d4f4 /lldb/source/Target/Process.cpp | |
parent | dae3c571894eaab432ef3c2a21da85576c8e13ef (diff) | |
download | bcm5719-llvm-fd4cea53d585904c58aef9c35b4a14f755bb30a9.tar.gz bcm5719-llvm-fd4cea53d585904c58aef9c35b4a14f755bb30a9.zip |
Re-apply r257117 (reverted in r257138 temporarily),
with the one change that ThreadPlanStepOut::ThreadPlanStepOut
will now only advance the return address breakpoint to
the end of a source line, if we have source line debug information.
It will not advance to the end of a Symbol if we lack source line
information. This, or the recognition of the LEAVE instruction
in r257209, would have fixed the regression that Siva was seeing.
Both were good changes, so I've made both.
Original commit message:
Performance improvement: Change lldb so that it puts a breakpoint
on the first branch instruction after a function return (or the end
of a source line), instead of a breakpoint on the return address,
to skip an extra stop & start of the inferior process.
I changed Process::AdvanceAddressToNextBranchInstruction to not
take an optional InstructionList argument - no callers are providing
a cached InstructionList today, and if this function was going to
do that, the right thing to do would be to fill out / use a
DisassemblerSP which is a disassembler with the InstructionList for
this address range.
http://reviews.llvm.org/D15708
<rdar://problem/23309838>
llvm-svn: 257210
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r-- | lldb/source/Target/Process.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 311c695860f..e4fe419660e 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -6515,3 +6515,65 @@ Process::ResetImageToken(size_t token) if (token < m_image_tokens.size()) m_image_tokens[token] = LLDB_INVALID_IMAGE_TOKEN; } + +Address +Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, AddressRange range_bounds) +{ + Target &target = GetTarget(); + DisassemblerSP disassembler_sp; + InstructionList *insn_list = NULL; + + Address retval = default_stop_addr; + + if (target.GetUseFastStepping() == false) + return retval; + if (default_stop_addr.IsValid() == false) + return retval; + + ExecutionContext exe_ctx (this); + const char *plugin_name = nullptr; + const char *flavor = nullptr; + const bool prefer_file_cache = true; + disassembler_sp = Disassembler::DisassembleRange(target.GetArchitecture(), + plugin_name, + flavor, + exe_ctx, + range_bounds, + prefer_file_cache); + if (disassembler_sp.get()) + insn_list = &disassembler_sp->GetInstructionList(); + + if (insn_list == NULL) + { + return retval; + } + + size_t insn_offset = insn_list->GetIndexOfInstructionAtAddress (default_stop_addr); + if (insn_offset == UINT32_MAX) + { + return retval; + } + + uint32_t branch_index = insn_list->GetIndexOfNextBranchInstruction (insn_offset, target); + if (branch_index == UINT32_MAX) + { + return retval; + } + + if (branch_index > insn_offset) + { + Address next_branch_insn_address = insn_list->GetInstructionAtIndex (branch_index)->GetAddress(); + if (next_branch_insn_address.IsValid() && range_bounds.ContainsFileAddress (next_branch_insn_address)) + { + retval = next_branch_insn_address; + } + } + + if (disassembler_sp.get()) + { + // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. + disassembler_sp->GetInstructionList().Clear(); + } + + return retval; +} |