Cleaned up the inline stack frame code one more time to prepare for inlined
code stepping. Also we now store the stack frames for the current and previous
stops in the thread in std::auto_ptr objects. When we create a thread stack
frame list we pass the previous frame into it so it can re-use the frames
and maintain will allow for variable changes to be detected. I will implement
the stack frame reuse next.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@112152 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index b6d252a..74c5ce7 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -41,7 +41,6 @@
lldb::user_id_t concrete_frame_index,
Thread &thread,
lldb::addr_t cfa,
- uint32_t inline_height,
lldb::addr_t pc,
const SymbolContext *sc_ptr
) :
@@ -49,7 +48,7 @@
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (),
- m_id (cfa, inline_height),
+ m_id (cfa, 0),
m_pc (NULL, pc),
m_sc (),
m_flags (),
@@ -72,7 +71,6 @@
Thread &thread,
const RegisterContextSP ®_context_sp,
lldb::addr_t cfa,
- uint32_t inline_height,
lldb::addr_t pc,
const SymbolContext *sc_ptr
) :
@@ -80,7 +78,7 @@
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (reg_context_sp),
- m_id (cfa, inline_height),
+ m_id (cfa, 0),
m_pc (NULL, pc),
m_sc (),
m_flags (),
@@ -109,7 +107,6 @@
Thread &thread,
const RegisterContextSP ®_context_sp,
lldb::addr_t cfa,
- uint32_t inline_height,
const Address& pc_addr,
const SymbolContext *sc_ptr
) :
@@ -117,7 +114,7 @@
m_concrete_frame_index (concrete_frame_index),
m_thread (thread),
m_reg_context_sp (reg_context_sp),
- m_id (cfa, inline_height),
+ m_id (cfa, 0),
m_pc (pc_addr),
m_sc (),
m_flags (),
@@ -473,12 +470,6 @@
return m_value_object_list;
}
-bool
-StackFrame::IsConcrete () const
-{
- return m_id.GetInlineHeight () == 0;
-}
-
Target *
StackFrame::CalculateTarget ()
{
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index 1ebe8a4..e8a436f 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -26,11 +26,12 @@
//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
-StackFrameList::StackFrameList(Thread &thread, bool show_inline_frames) :
+StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) :
m_thread (thread),
+ m_prev_frames_ap (prev_frames),
m_show_inlined_frames (show_inline_frames),
m_mutex (Mutex::eMutexTypeRecursive),
- m_actual_frames (),
+ m_unwind_frames (),
m_inline_frames (),
m_current_frame_idx (0)
{
@@ -51,13 +52,13 @@
if (m_show_inlined_frames)
{
- if (m_inlined_frame_info.empty())
+ if (m_inlined_info.empty())
{
Unwind *unwinder = m_thread.GetUnwinder ();
// If we are going to show inlined stack frames as actual frames,
// we need to calculate all concrete frames first, then iterate
// through all of them and count up how many inlined functions are
- // in each frame. We can then fill in m_inlined_frame_info with
+ // in each frame. We can then fill in m_inlined_info with
// the concrete frame index and inlined depth
const uint32_t concrete_frame_count = unwinder->GetFrameCount();
@@ -75,7 +76,6 @@
m_thread,
m_thread.m_reg_context_sp,
m_thread.m_reg_context_sp->GetSP(),
- 0,
m_thread.m_reg_context_sp->GetPC(),
NULL));
}
@@ -83,52 +83,51 @@
{
const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
assert (success);
- frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, m_thread, cfa, 0, pc, NULL));
+ frame_sp.reset (new StackFrame (m_inlined_info.size(), idx, m_thread, cfa, pc, NULL));
}
- SetActualFrameAtIndex (idx, frame_sp);
+ SetUnwindFrameAtIndex (idx, frame_sp);
Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block;
- inlined_frame_info.concrete_frame_index = idx;
- inlined_frame_info.inline_height = 0;
- inlined_frame_info.block = block;
- m_inlined_frame_info.push_back (inlined_frame_info);
+ inlined_frame_info.unwind_frame_index = idx;
+ inlined_frame_info.block = NULL;
+ m_inlined_info.push_back (inlined_frame_info);
if (block)
{
- Block *inlined_block;
- if (block->InlinedFunctionInfo())
- inlined_block = block;
- else
- inlined_block = block->GetInlinedParent ();
-
- while (inlined_block)
+ Block *inlined_block = block->GetContainingInlinedBlock();
+
+ if (inlined_block)
{
- inlined_frame_info.block = inlined_block;
- inlined_frame_info.inline_height++;
- m_inlined_frame_info.push_back (inlined_frame_info);
- inlined_block = inlined_block->GetInlinedParent ();
+ frame_sp->SetInlineBlockID (inlined_block->GetID());
+
+ while (inlined_block)
+ {
+ inlined_frame_info.block = inlined_block;
+ m_inlined_info.push_back (inlined_frame_info);
+ inlined_block = inlined_block->GetInlinedParent ();
+ }
}
}
}
}
- return m_inlined_frame_info.size();
+ return m_inlined_info.size();
}
else
{
- if (m_actual_frames.empty())
- m_actual_frames.resize(m_thread.GetUnwinder()->GetFrameCount());
+ if (m_unwind_frames.empty())
+ m_unwind_frames.resize(m_thread.GetUnwinder()->GetFrameCount());
- return m_actual_frames.size();
+ return m_unwind_frames.size();
}
return 0;
}
lldb::StackFrameSP
-StackFrameList::GetActualFrameAtIndex (uint32_t idx) const
+StackFrameList::GetUnwindFrameAtIndex (uint32_t idx) const
{
StackFrameSP frame_sp;
- if (idx < m_actual_frames.size())
- frame_sp = m_actual_frames[idx];
+ if (idx < m_unwind_frames.size())
+ frame_sp = m_unwind_frames[idx];
return frame_sp;
}
@@ -155,118 +154,138 @@
}
else
{
- frame_sp = GetActualFrameAtIndex (idx);
+ frame_sp = GetUnwindFrameAtIndex (idx);
}
if (frame_sp.get())
- return frame_sp;
+ return frame_sp;
- // Special case the first frame (idx == 0) so that we don't need to
- // know how many stack frames there are to get it. If we need any other
- // frames, then we do need to know if "idx" is a valid index.
- if (idx == 0)
- {
- // If this is the first frame, we want to share the thread register
- // context with the stack frame at index zero.
- m_thread.GetRegisterContext();
- assert (m_thread.m_reg_context_sp.get());
- frame_sp.reset (new StackFrame (0,
- 0,
- m_thread,
- m_thread.m_reg_context_sp,
- m_thread.m_reg_context_sp->GetSP(),
- 0,
- m_thread.m_reg_context_sp->GetPC(),
- NULL));
- }
- else if (idx < GetNumFrames())
- {
+ // Special case the first frame (idx == 0) so that we don't need to
+ // know how many stack frames there are to get it. If we need any other
+ // frames, then we do need to know if "idx" is a valid index.
+ if (idx == 0)
+ {
+ // If this is the first frame, we want to share the thread register
+ // context with the stack frame at index zero.
+ m_thread.GetRegisterContext();
+ assert (m_thread.m_reg_context_sp.get());
+ frame_sp.reset (new StackFrame (0,
+ 0,
+ m_thread,
+ m_thread.m_reg_context_sp,
+ m_thread.m_reg_context_sp->GetSP(),
+ m_thread.m_reg_context_sp->GetPC(),
+ NULL));
+
+ if (m_show_inlined_frames && idx + 1 < m_inlined_info.size())
+ {
+ if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
+ frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID());
+ }
+
+ }
+ else if (idx < GetNumFrames())
+ {
+ if (m_show_inlined_frames)
+ {
+ if (m_inlined_info[idx].block == NULL)
+ {
+ // Same as the concrete stack frame if block is NULL
+ assert (m_inlined_info[idx].unwind_frame_index < m_unwind_frames.size());
+ frame_sp = GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index);
+ if (idx + 1 < m_inlined_info.size())
+ {
+ if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
+ frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID());
+ }
+ }
+ else
+ {
+ // We have blocks that were above an inlined function. Inlined
+ // functions are represented as blocks with non-NULL inline
+ // function info. Here we must reconstruct a frame by looking
+ // at the block
+ StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1));
+
+ SymbolContext inline_sc;
+
+ Block *inlined_parent_block = m_inlined_info[idx].block->GetInlinedParent();
+
+ if (inlined_parent_block)
+ inlined_parent_block->CalculateSymbolContext (&inline_sc);
+ else
+ {
+ Block *parent_block = m_inlined_info[idx].block->GetParent();
+ parent_block->CalculateSymbolContext(&inline_sc);
+ }
+
+ Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress());
+ if (previous_frame_sp->GetFrameIndex() > 0 && m_inlined_info[idx-1].block == NULL)
+ previous_frame_lookup_addr.Slide (-1);
+
+ AddressRange range;
+ m_inlined_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
+
+ const InlineFunctionInfo* inline_info = m_inlined_info[idx].block->InlinedFunctionInfo();
+ assert (inline_info);
+ inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress();
+ inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
+ inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
+ inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
+
+ StackFrameSP concrete_frame_sp (GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index));
+ assert (previous_frame_sp.get());
+
+ frame_sp.reset (new StackFrame (idx,
+ m_inlined_info[idx].unwind_frame_index,
+ m_thread,
+ concrete_frame_sp->GetRegisterContextSP (),
+ concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA
+ range.GetBaseAddress(),
+ &inline_sc)); // The symbol context for this inline frame
+
+ if (idx + 1 < m_inlined_info.size())
+ {
+ if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index)
+ frame_sp->SetInlineBlockID (m_inlined_info[idx].block->GetID());
+ }
+ }
+ }
+ else
+ {
+ Unwind *unwinder = m_thread.GetUnwinder ();
+ if (unwinder)
+ {
+ addr_t pc, cfa;
+ if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
+ frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL));
+ }
+ }
+ }
+
if (m_show_inlined_frames)
{
- if (m_inlined_frame_info[idx].inline_height == 0)
- {
- // Same as the concrete stack frame if block is NULL
- assert (m_inlined_frame_info[idx].concrete_frame_index < m_actual_frames.size());
- frame_sp = GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index);
- }
- else
- {
- // We have blocks that were above an inlined function. Inlined
- // functions are represented as blocks with non-NULL inline
- // function info. Here we must reconstruct a frame by looking
- // at the block
- StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1));
-
- SymbolContext inline_sc;
-
- Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent();
-
- if (inlined_parent_block)
- inlined_parent_block->CalculateSymbolContext (&inline_sc);
- else
- {
- Block *parent_block = m_inlined_frame_info[idx].block->GetParent();
- parent_block->CalculateSymbolContext(&inline_sc);
- }
-
- Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress());
- if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0)
- previous_frame_lookup_addr.Slide (-1);
-
- AddressRange range;
- m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range);
-
- const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo();
- assert (inline_info);
- inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress();
- inline_sc.line_entry.file = inline_info->GetCallSite().GetFile();
- inline_sc.line_entry.line = inline_info->GetCallSite().GetLine();
- inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn();
-
- StackFrameSP concrete_frame_sp (GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index));
- assert (previous_frame_sp.get());
-
- frame_sp.reset (new StackFrame (idx,
- m_inlined_frame_info[idx].concrete_frame_index,
- m_thread,
- concrete_frame_sp->GetRegisterContextSP (),
- concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA
- m_inlined_frame_info[idx].inline_height, // Inline height
- range.GetBaseAddress(),
- &inline_sc)); // The symbol context for this inline frame
-
- }
+ SetInlineFrameAtIndex(idx, frame_sp);
}
else
{
- Unwind *unwinder = m_thread.GetUnwinder ();
- if (unwinder)
- {
- addr_t pc, cfa;
- if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
- frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, 0, pc, NULL));
- }
+ SetUnwindFrameAtIndex(idx, frame_sp);
}
- }
- if (m_show_inlined_frames)
- SetInlineFrameAtIndex(idx, frame_sp);
- else
- SetActualFrameAtIndex(idx, frame_sp);
- return frame_sp;
-
+ return frame_sp;
+
}
return frame_sp;
}
bool
-StackFrameList::SetActualFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
+StackFrameList::SetUnwindFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
{
- if (idx >= m_actual_frames.size())
- m_actual_frames.resize(idx + 1);
+ if (idx >= m_unwind_frames.size())
+ m_unwind_frames.resize(idx + 1);
// Make sure allocation succeeded by checking bounds again
- if (idx < m_actual_frames.size())
+ if (idx < m_unwind_frames.size())
{
- m_actual_frames[idx] = frame_sp;
+ m_unwind_frames[idx] = frame_sp;
return true;
}
return false; // resize failed, out of memory?
@@ -299,8 +318,8 @@
{
Mutex::Locker locker (m_mutex);
const_iterator pos;
- const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_actual_frames.begin();
- const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_actual_frames.end();
+ const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_unwind_frames.begin();
+ const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_unwind_frames.end();
for (pos = begin; pos != end; ++pos)
{
if (pos->get() == frame)
@@ -327,9 +346,9 @@
StackFrameList::Clear ()
{
Mutex::Locker locker (m_mutex);
- m_actual_frames.clear();
+ m_unwind_frames.clear();
m_inline_frames.clear();
- m_inlined_frame_info.clear();
+ m_inlined_info.clear();
}
void
@@ -342,10 +361,10 @@
}
else
{
- const size_t num_frames = m_actual_frames.size();
+ const size_t num_frames = m_unwind_frames.size();
while (start_idx < num_frames)
{
- m_actual_frames[start_idx].reset();
+ m_unwind_frames[start_idx].reset();
++start_idx;
}
}
diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp
index 78543fa..6d34d3b 100644
--- a/source/Target/StackID.cpp
+++ b/source/Target/StackID.cpp
@@ -16,84 +16,27 @@
using namespace lldb_private;
-//----------------------------------------------------------------------
-// StackID constructor
-//----------------------------------------------------------------------
-StackID::StackID() :
- m_start_address(),
- m_cfa (0),
- m_inline_height (0)
-{
-}
-
-//----------------------------------------------------------------------
-// StackID constructor with args
-//----------------------------------------------------------------------
-StackID::StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id) :
- m_start_address (start_address),
- m_cfa (cfa),
- m_inline_height (inline_id)
-{
-}
-
-StackID::StackID (lldb::addr_t cfa, uint32_t inline_id) :
- m_start_address (),
- m_cfa (cfa),
- m_inline_height (inline_id)
-{
-}
-
-//----------------------------------------------------------------------
-// StackID copy constructor
-//----------------------------------------------------------------------
-StackID::StackID(const StackID& rhs) :
- m_start_address (rhs.m_start_address),
- m_cfa (rhs.m_cfa),
- m_inline_height (rhs.m_inline_height)
-{
-}
-
-//----------------------------------------------------------------------
-// StackID assignment operator
-//----------------------------------------------------------------------
-const StackID&
-StackID::operator=(const StackID& rhs)
-{
- if (this != &rhs)
- {
- m_start_address = rhs.m_start_address;
- m_cfa = rhs.m_cfa;
- m_inline_height = rhs.m_inline_height;
- }
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-StackID::~StackID()
-{
-}
bool
lldb_private::operator== (const StackID& lhs, const StackID& rhs)
{
- return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() &&
- lhs.GetInlineHeight() == rhs.GetInlineHeight() &&
- lhs.GetStartAddress() == rhs.GetStartAddress();
+ return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() &&
+ lhs.GetInlineBlockID() == rhs.GetInlineBlockID() &&
+ lhs.GetStartAddress() == rhs.GetStartAddress();
}
bool
lldb_private::operator!= (const StackID& lhs, const StackID& rhs)
{
- return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() ||
- lhs.GetInlineHeight() != rhs.GetInlineHeight() ||
- lhs.GetStartAddress() != rhs.GetStartAddress();
+ return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() ||
+ lhs.GetInlineBlockID() != rhs.GetInlineBlockID() ||
+ lhs.GetStartAddress() != rhs.GetStartAddress();
}
bool
lldb_private::operator< (const StackID& lhs, const StackID& rhs)
{
- return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress();
+ if (lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress())
+ return true;
+ return lhs.GetInlineBlockID() < rhs.GetInlineBlockID();
}
-
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 97dd52f..ff3cf6d 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -49,7 +49,7 @@
m_plan_stack (),
m_immediate_plan_stack(),
m_completed_plan_stack(),
- m_frames_sp (),
+ m_curr_frames_ap (),
m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
m_resume_state (eStateRunning),
m_unwinder_ap ()
@@ -796,9 +796,9 @@
StackFrameList &
Thread::GetStackFrameList ()
{
- if (m_frames_sp.get() == NULL)
- m_frames_sp.reset (new StackFrameList (*this, true));
- return *m_frames_sp;
+ if (m_curr_frames_ap.get() == NULL)
+ m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_ap.release(), true));
+ return *m_curr_frames_ap;
}
@@ -813,8 +813,7 @@
void
Thread::ClearStackFrames ()
{
- if (m_frames_sp)
- m_frames_sp->Clear();
+ m_prev_frames_ap = m_curr_frames_ap;
}
lldb::StackFrameSP