1 //===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/StackFrameList.h"
15 #include "lldb/Target/StackFrame.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 //----------------------------------------------------------------------
21 // StackFrameList constructor
22 //----------------------------------------------------------------------
23 StackFrameList::StackFrameList() :
24     m_mutex (Mutex::eMutexTypeRecursive),
25     m_frames (),
26     m_current_frame_idx (0)
27 {
28 }
29 
30 //----------------------------------------------------------------------
31 // Destructor
32 //----------------------------------------------------------------------
33 StackFrameList::~StackFrameList()
34 {
35 }
36 
37 
38 uint32_t
39 StackFrameList::GetNumFrames() const
40 {
41     Mutex::Locker locker (m_mutex);
42     return m_frames.size();
43 }
44 
45 // After we have determined the number of frames, we can set the count here
46 // and have the frame info be generated on demand.
47 void
48 StackFrameList::SetNumFrames(uint32_t count)
49 {
50     Mutex::Locker locker (m_mutex);
51     return m_frames.resize(count);
52 }
53 
54 StackFrameSP
55 StackFrameList::GetFrameAtIndex (uint32_t idx) const
56 {
57     StackFrameSP frame_sp;
58     {
59         Mutex::Locker locker (m_mutex);
60         if (idx < m_frames.size())
61             frame_sp = m_frames[idx];
62     }
63     return frame_sp;
64 }
65 
66 bool
67 StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
68 {
69     Mutex::Locker locker (m_mutex);
70     if (idx >= m_frames.size())
71         m_frames.resize(idx + 1);
72     // Make sure allocation succeeded by checking bounds again
73     if (idx < m_frames.size())
74     {
75         m_frames[idx] = frame_sp;
76         return true;
77     }
78     return false;   // resize failed, out of memory?
79 }
80 
81 uint32_t
82 StackFrameList::GetCurrentFrameIndex () const
83 {
84     Mutex::Locker locker (m_mutex);
85     return m_current_frame_idx;
86 }
87 
88 
89 uint32_t
90 StackFrameList::SetCurrentFrame (lldb_private::StackFrame *frame)
91 {
92     Mutex::Locker locker (m_mutex);
93     const_iterator pos,
94                    begin = m_frames.begin(),
95                    end = m_frames.end();
96     for (pos = begin; pos != end; ++pos)
97     {
98         if (pos->get() == frame)
99         {
100             m_current_frame_idx = std::distance (begin, pos);
101             return m_current_frame_idx;
102         }
103     }
104     m_current_frame_idx = 0;
105     return m_current_frame_idx;
106 }
107 
108 // Mark a stack frame as the current frame using the frame index
109 void
110 StackFrameList::SetCurrentFrameByIndex (uint32_t idx)
111 {
112     Mutex::Locker locker (m_mutex);
113     m_current_frame_idx = idx;
114 }
115 
116 // The thread has been run, reset the number stack frames to zero so we can
117 // determine how many frames we have lazily.
118 void
119 StackFrameList::Clear ()
120 {
121     Mutex::Locker locker (m_mutex);
122     m_frames.clear();
123 }
124 
125 void
126 StackFrameList::InvalidateFrames (uint32_t start_idx)
127 {
128     Mutex::Locker locker (m_mutex);
129     size_t num_frames = m_frames.size();
130     while (start_idx < num_frames)
131     {
132         m_frames[start_idx].reset();
133         ++start_idx;
134     }
135 }
136