forked from OSchip/llvm-project
When constructing an address range to "step" or "next" through,
find the largest address range (possibly combining multiple LineEntry's for this line number) that is contiguous. This allows lldb's fast-step stepping algorithm to potentially run for a longer address range than if we have to stop at every LineEntry indicating a subexpression in the source line. http://reviews.llvm.org/D15407 <rdar://problem/23270882> llvm-svn: 255590
This commit is contained in:
parent
ef0ef2860d
commit
25d5b10b22
|
@ -140,6 +140,32 @@ struct LineEntry
|
|||
static int
|
||||
Compare (const LineEntry& lhs, const LineEntry& rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Give the range for this LineEntry + any additional LineEntries for
|
||||
/// this same source line that are contiguous.
|
||||
///
|
||||
/// A compiler may emit multiple line entries for a single source line,
|
||||
/// e.g. to indicate subexpressions at different columns. This method
|
||||
/// will get the AddressRange for all of the LineEntries for this source
|
||||
/// line that are contiguous.
|
||||
//
|
||||
/// Line entries with a line number of 0 are treated specially - these
|
||||
/// are compiler-generated line table entries that the user did not
|
||||
/// write in their source code, and we want to skip past in the debugger.
|
||||
/// If this LineEntry is for line 32, and the following LineEntry is for
|
||||
/// line 0, we will extend the range to include the AddressRange of the
|
||||
/// line 0 LineEntry (and it will include the range of the following
|
||||
/// LineEntries that match either 32 or 0.)
|
||||
///
|
||||
/// If the initial LineEntry this method is called on is a line #0, only
|
||||
/// the range of contiuous LineEntries with line #0 will be included in
|
||||
/// the complete range.
|
||||
///
|
||||
/// @return
|
||||
/// The contiguous AddressRange for this source line.
|
||||
//------------------------------------------------------------------
|
||||
AddressRange
|
||||
GetSameLineContiguousAddressRange () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
|
|
|
@ -754,6 +754,15 @@ public:
|
|||
lldb::RunMode stop_other_threads,
|
||||
LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
|
||||
|
||||
// Helper function that takes a LineEntry to step, insted of an AddressRange. This may combine multiple
|
||||
// LineEntries of the same source line number to step over a longer address range in a single operation.
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepOverRange (bool abort_other_plans,
|
||||
const LineEntry &line_entry,
|
||||
const SymbolContext &addr_context,
|
||||
lldb::RunMode stop_other_threads,
|
||||
LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Queues the plan used to step through an address range, stepping into functions.
|
||||
///
|
||||
|
@ -800,6 +809,17 @@ public:
|
|||
LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
|
||||
LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
|
||||
|
||||
// Helper function that takes a LineEntry to step, insted of an AddressRange. This may combine multiple
|
||||
// LineEntries of the same source line number to step over a longer address range in a single operation.
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepInRange (bool abort_other_plans,
|
||||
const LineEntry &line_entry,
|
||||
const SymbolContext &addr_context,
|
||||
const char *step_in_target,
|
||||
lldb::RunMode stop_other_threads,
|
||||
LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
|
||||
LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Queue the plan used to step out of the function at the current PC of
|
||||
/// \a thread.
|
||||
|
|
|
@ -747,7 +747,7 @@ SBThread::StepOver (lldb::RunMode stop_other_threads)
|
|||
const LazyBool avoid_no_debug = eLazyBoolCalculate;
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc.line_entry,
|
||||
sc,
|
||||
stop_other_threads,
|
||||
avoid_no_debug);
|
||||
|
@ -799,7 +799,7 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
|
|||
const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc.line_entry,
|
||||
sc,
|
||||
target_name,
|
||||
stop_other_threads,
|
||||
|
|
|
@ -586,7 +586,7 @@ protected:
|
|||
if (frame->HasDebugInformation ())
|
||||
{
|
||||
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry,
|
||||
frame->GetSymbolContext(eSymbolContextEverything),
|
||||
m_options.m_step_in_target.c_str(),
|
||||
stop_other_threads,
|
||||
|
@ -609,7 +609,7 @@ protected:
|
|||
|
||||
if (frame->HasDebugInformation())
|
||||
new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry,
|
||||
frame->GetSymbolContext(eSymbolContextEverything),
|
||||
stop_other_threads,
|
||||
m_options.m_step_out_avoid_no_debug);
|
||||
|
|
|
@ -244,3 +244,42 @@ LineEntry::Compare (const LineEntry& a, const LineEntry& b)
|
|||
return FileSpec::Compare (a.file, b.file, true);
|
||||
}
|
||||
|
||||
AddressRange
|
||||
LineEntry::GetSameLineContiguousAddressRange () const
|
||||
{
|
||||
// Add each LineEntry's range to complete_line_range until we find
|
||||
// a different file / line number.
|
||||
AddressRange complete_line_range = range;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SymbolContext next_line_sc;
|
||||
Address range_end (complete_line_range.GetBaseAddress());
|
||||
range_end.Slide (complete_line_range.GetByteSize());
|
||||
range_end.CalculateSymbolContext (&next_line_sc, lldb::eSymbolContextLineEntry);
|
||||
|
||||
if (next_line_sc.line_entry.IsValid()
|
||||
&& next_line_sc.line_entry.range.GetByteSize() > 0
|
||||
&& file == next_line_sc.line_entry.file)
|
||||
{
|
||||
// Include any line 0 entries - they indicate that this is compiler-generated code
|
||||
// that does not correspond to user source code.
|
||||
if (next_line_sc.line_entry.line == 0)
|
||||
{
|
||||
complete_line_range.SetByteSize (complete_line_range.GetByteSize() + next_line_sc.line_entry.range.GetByteSize());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line == next_line_sc.line_entry.line)
|
||||
{
|
||||
// next_line_sc is the same file & line as this LineEntry, so extend our
|
||||
// AddressRange by its size and continue to see if there are more LineEntries
|
||||
// that we can combine.
|
||||
complete_line_range.SetByteSize (complete_line_range.GetByteSize() + next_line_sc.line_entry.range.GetByteSize());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return complete_line_range;
|
||||
}
|
||||
|
|
|
@ -1535,6 +1535,21 @@ Thread::QueueThreadPlanForStepOverRange(bool abort_other_plans,
|
|||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
// Call the QueueThreadPlanForStepOverRange method which takes an address range.
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOverRange(bool abort_other_plans,
|
||||
const LineEntry &line_entry,
|
||||
const SymbolContext &addr_context,
|
||||
lldb::RunMode stop_other_threads,
|
||||
LazyBool step_out_avoids_code_withoug_debug_info)
|
||||
{
|
||||
return QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
line_entry.GetSameLineContiguousAddressRange(),
|
||||
addr_context,
|
||||
stop_other_threads,
|
||||
step_out_avoids_code_withoug_debug_info);
|
||||
}
|
||||
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepInRange(bool abort_other_plans,
|
||||
const AddressRange &range,
|
||||
|
@ -1559,6 +1574,26 @@ Thread::QueueThreadPlanForStepInRange(bool abort_other_plans,
|
|||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
// Call the QueueThreadPlanForStepInRange method which takes an address range.
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepInRange(bool abort_other_plans,
|
||||
const LineEntry &line_entry,
|
||||
const SymbolContext &addr_context,
|
||||
const char *step_in_target,
|
||||
lldb::RunMode stop_other_threads,
|
||||
LazyBool step_in_avoids_code_without_debug_info,
|
||||
LazyBool step_out_avoids_code_without_debug_info)
|
||||
{
|
||||
return QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
line_entry.GetSameLineContiguousAddressRange(),
|
||||
addr_context,
|
||||
step_in_target,
|
||||
stop_other_threads,
|
||||
step_in_avoids_code_without_debug_info,
|
||||
step_out_avoids_code_without_debug_info);
|
||||
}
|
||||
|
||||
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOut(bool abort_other_plans,
|
||||
SymbolContext *addr_context,
|
||||
|
@ -2374,7 +2409,7 @@ Thread::StepIn (bool source_step,
|
|||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc.line_entry,
|
||||
sc,
|
||||
NULL,
|
||||
run_mode,
|
||||
|
@ -2420,7 +2455,7 @@ Thread::StepOver (bool source_step,
|
|||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc.line_entry,
|
||||
sc,
|
||||
run_mode,
|
||||
step_out_avoids_code_without_debug_info);
|
||||
|
|
|
@ -162,7 +162,7 @@ ThreadPlanStepRange::InRange ()
|
|||
if (m_addr_context.line_entry.line == new_context.line_entry.line)
|
||||
{
|
||||
m_addr_context = new_context;
|
||||
AddRange(m_addr_context.line_entry.range);
|
||||
AddRange(m_addr_context.line_entry.GetSameLineContiguousAddressRange());
|
||||
ret_value = true;
|
||||
if (log)
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ ThreadPlanStepRange::InRange ()
|
|||
{
|
||||
new_context.line_entry.line = m_addr_context.line_entry.line;
|
||||
m_addr_context = new_context;
|
||||
AddRange(m_addr_context.line_entry.range);
|
||||
AddRange(m_addr_context.line_entry.GetSameLineContiguousAddressRange());
|
||||
ret_value = true;
|
||||
if (log)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue