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:
Jason Molenda 2015-12-15 00:40:30 +00:00
parent ef0ef2860d
commit 25d5b10b22
7 changed files with 128 additions and 8 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{