//===-- StackFrameList.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/StackFrameList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Unwind.h"

//#define DEBUG_STACK_FRAMES 1

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// StackFrameList constructor
//----------------------------------------------------------------------
StackFrameList::StackFrameList
(
    Thread &thread, 
    const lldb::StackFrameListSP &prev_frames_sp, 
    bool show_inline_frames
) :
    m_thread (thread),
    m_prev_frames_sp (prev_frames_sp),
    m_mutex (Mutex::eMutexTypeRecursive),
    m_frames (),
    m_selected_frame_idx (0),
    m_concrete_frames_fetched (0),
    m_current_inlined_depth (UINT32_MAX),
    m_current_inlined_pc (LLDB_INVALID_ADDRESS),
    m_show_inlined_frames (show_inline_frames)
{
    if (prev_frames_sp)
    {
        m_current_inlined_depth = prev_frames_sp->m_current_inlined_depth;
        m_current_inlined_pc =    prev_frames_sp->m_current_inlined_pc;
    }
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
StackFrameList::~StackFrameList()
{
    // Call clear since this takes a lock and clears the stack frame list
    // in case another thread is currently using this stack frame list
    Clear();
}

void
StackFrameList::CalculateCurrentInlinedDepth()
{
    uint32_t cur_inlined_depth = GetCurrentInlinedDepth();
    if (cur_inlined_depth == UINT32_MAX)
    {
        ResetCurrentInlinedDepth();
    }
}

uint32_t
StackFrameList::GetCurrentInlinedDepth ()
{
    if (m_show_inlined_frames && m_current_inlined_pc != LLDB_INVALID_ADDRESS)
    {
        lldb::addr_t cur_pc = m_thread.GetRegisterContext()->GetPC();
        if (cur_pc != m_current_inlined_pc)
        {
            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
            m_current_inlined_depth = UINT32_MAX;
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
            if (log && log->GetVerbose())
                log->Printf ("GetCurrentInlinedDepth: invalidating current inlined depth.\n");
        }
        return m_current_inlined_depth;
    }
    else
    {
        return UINT32_MAX;
    }
}

void
StackFrameList::ResetCurrentInlinedDepth ()
{
    if (m_show_inlined_frames)
    {        
        GetFramesUpTo(0);
        if (!m_frames[0]->IsInlined())
        {
            m_current_inlined_depth = UINT32_MAX;
            m_current_inlined_pc = LLDB_INVALID_ADDRESS;
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
            if (log && log->GetVerbose())
                log->Printf ("ResetCurrentInlinedDepth: Invalidating current inlined depth.\n");
        }
        else
        {
            // We only need to do something special about inlined blocks when we
            // are at the beginning of an inlined function:
            // FIXME: We probably also have to do something special if the PC is at the END
            // of an inlined function, which coincides with the end of either its containing
            // function or another inlined function.
            
            lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC();
            Block *block_ptr = m_frames[0]->GetFrameBlock();
            if (block_ptr)
            {
                Address pc_as_address;
                pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget()));
                AddressRange containing_range;
                if (block_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
                {
                    if (pc_as_address == containing_range.GetBaseAddress())
                    {
                        // If we got here because of a breakpoint hit, then set the inlined depth depending on where
                        // the breakpoint was set.
                        // If we got here because of a crash, then set the inlined depth to the deepest most block.
                        // Otherwise, we stopped here naturally as the result of a step, so set ourselves in the
                        // containing frame of the whole set of nested inlines, so the user can then "virtually"
                        // step into the frames one by one, or next over the whole mess.
                        // Note: We don't have to handle being somewhere in the middle of the stack here, since
                        // ResetCurrentInlinedDepth doesn't get called if there is a valid inlined depth set.
                        StopInfoSP stop_info_sp = m_thread.GetStopInfo();
                        if (stop_info_sp)
                        {
                            switch (stop_info_sp->GetStopReason())
                            {
                            case eStopReasonWatchpoint:
                            case eStopReasonException:
                            case eStopReasonExec:
                            case eStopReasonSignal:
                                // In all these cases we want to stop in the deepest most frame.
                                m_current_inlined_pc = curr_pc;
                                m_current_inlined_depth = 0;
                                break;
                            case eStopReasonBreakpoint:
                                {
                                    // FIXME: Figure out what this break point is doing, and set the inline depth
                                    // appropriately.  Be careful to take into account breakpoints that implement
                                    // step over prologue, since that should do the default calculation.
                                    // For now, if the breakpoints corresponding to this hit are all internal,
                                    // I set the stop location to the top of the inlined stack, since that will make
                                    // things like stepping over prologues work right.  But if there are any non-internal
                                    // breakpoints I do to the bottom of the stack, since that was the old behavior.
                                    uint32_t bp_site_id = stop_info_sp->GetValue();
                                    BreakpointSiteSP bp_site_sp(m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id));
                                    bool all_internal = true;
                                    if (bp_site_sp)
                                    {
                                        uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
                                        for (uint32_t i = 0; i < num_owners; i++)
                                        {
                                            Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
                                            if (!bp_ref.IsInternal())
                                            {
                                                all_internal = false;
                                            }
                                        }
                                    }
                                    if (!all_internal)
                                    {
                                        m_current_inlined_pc = curr_pc;
                                        m_current_inlined_depth = 0;
                                        break;
                                    }
                                }
                            default:
                                {
                                    // Otherwise, we should set ourselves at the container of the inlining, so that the
                                    // user can descend into them.
                                    // So first we check whether we have more than one inlined block sharing this PC:
                                    int num_inlined_functions = 0;
                                    
                                    for  (Block *container_ptr = block_ptr->GetInlinedParent();
                                              container_ptr != NULL;
                                              container_ptr = container_ptr->GetInlinedParent())
                                    {
                                        if (!container_ptr->GetRangeContainingAddress(pc_as_address, containing_range))
                                            break;
                                        if (pc_as_address != containing_range.GetBaseAddress())
                                            break;
                                        
                                        num_inlined_functions++;
                                    }
                                    m_current_inlined_pc = curr_pc;
                                    m_current_inlined_depth = num_inlined_functions + 1;
                                    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
                                    if (log && log->GetVerbose())
                                        log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%" PRIx64 ".\n", m_current_inlined_depth, curr_pc);
                                    
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}

bool
StackFrameList::DecrementCurrentInlinedDepth ()
{
    if (m_show_inlined_frames)
    {
        uint32_t current_inlined_depth = GetCurrentInlinedDepth();
        if (current_inlined_depth != UINT32_MAX)
        {
            if (current_inlined_depth > 0)
            {
                m_current_inlined_depth--;
                return true;
            }
        }
    }
    return false;
}

void
StackFrameList::SetCurrentInlinedDepth (uint32_t new_depth)
{
    m_current_inlined_depth = new_depth;
    if (new_depth == UINT32_MAX)
        m_current_inlined_pc = LLDB_INVALID_ADDRESS;
    else
        m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC();
}

void
StackFrameList::GetFramesUpTo(uint32_t end_idx)
{
    // this makes sure we do not fetch frames for an invalid thread
    if (m_thread.IsValid() == false)
        return;

    // We've already gotten more frames than asked for, or we've already finished unwinding, return.
    if (m_frames.size() > end_idx || GetAllFramesFetched())
        return;
        
    Unwind *unwinder = m_thread.GetUnwinder ();

    if (m_show_inlined_frames)
    {
#if defined (DEBUG_STACK_FRAMES)
        StreamFile s(stdout, false);
#endif
        // If we are hiding some frames from the outside world, we need to add those onto the total count of
        // frames to fetch.  However, we don't need to do that if end_idx is 0 since in that case we always
        // get the first concrete frame and all the inlined frames below it...  And of course, if end_idx is
        // UINT32_MAX that means get all, so just do that...
        
        uint32_t inlined_depth = 0;
        if (end_idx > 0 && end_idx != UINT32_MAX)
        {
            inlined_depth = GetCurrentInlinedDepth();
            if (inlined_depth != UINT32_MAX)
            {
                if (end_idx > 0)
                    end_idx += inlined_depth;
            }
        }
        
        StackFrameSP unwind_frame_sp;
        do
        {
            uint32_t idx = m_concrete_frames_fetched++;
            lldb::addr_t pc = LLDB_INVALID_ADDRESS;
            lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
            if (idx == 0)
            {
                // We might have already created frame zero, only create it
                // if we need to
                if (m_frames.empty())
                {
                    RegisterContextSP reg_ctx_sp (m_thread.GetRegisterContext());
                    
                    if (reg_ctx_sp)
                    {

                        const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
                        // There shouldn't be any way not to get the frame info for frame 0.
                        // But if the unwinder can't make one, lets make one by hand with the
                        // SP as the CFA and see if that gets any further.
                        if (!success)
                        {
                            cfa = reg_ctx_sp->GetSP();
                            pc = reg_ctx_sp->GetPC();
                        }
                        
                        unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(),
                                                               m_frames.size(), 
                                                               idx,
                                                               reg_ctx_sp,
                                                               cfa,
                                                               pc,
                                                               NULL));
                        m_frames.push_back (unwind_frame_sp);
                    }
                }
                else
                {
                    unwind_frame_sp = m_frames.front();
                    cfa = unwind_frame_sp->m_id.GetCallFrameAddress();
                }
            }
            else
            {
                const bool success = unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc);
                if (!success)
                {
                    // We've gotten to the end of the stack.
                    SetAllFramesFetched();
                    break;
                }
                const bool cfa_is_valid = true;
                const bool stop_id_is_valid = false;
                const bool is_history_frame = false;
                unwind_frame_sp.reset (new StackFrame (m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL));
                m_frames.push_back (unwind_frame_sp);
            }
            
            SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock | eSymbolContextFunction);
            Block *unwind_block = unwind_sc.block;
            if (unwind_block)
            {
                Address curr_frame_address (unwind_frame_sp->GetFrameCodeAddress());
                // Be sure to adjust the frame address to match the address
                // that was used to lookup the symbol context above. If we are
                // in the first concrete frame, then we lookup using the current
                // address, else we decrement the address by one to get the correct
                // location.
                if (idx > 0)
                    curr_frame_address.Slide(-1);
                    
                SymbolContext next_frame_sc;
                Address next_frame_address;
                
                while (unwind_sc.GetParentOfInlinedScope(curr_frame_address, next_frame_sc, next_frame_address))
                {
                        StackFrameSP frame_sp(new StackFrame (m_thread.shared_from_this(),
                                                              m_frames.size(),
                                                              idx,
                                                              unwind_frame_sp->GetRegisterContextSP (),
                                                              cfa,
                                                              next_frame_address,
                                                              &next_frame_sc));  
                                                    
                        m_frames.push_back (frame_sp);
                        unwind_sc = next_frame_sc;
                        curr_frame_address = next_frame_address;
                }
            }
        } while (m_frames.size() - 1 < end_idx);

        // Don't try to merge till you've calculated all the frames in this stack.
        if (GetAllFramesFetched() && m_prev_frames_sp)
        {
            StackFrameList *prev_frames = m_prev_frames_sp.get();
            StackFrameList *curr_frames = this;
            
            //curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
            //curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
            //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);

#if defined (DEBUG_STACK_FRAMES)
            s.PutCString("\nprev_frames:\n");
            prev_frames->Dump (&s);
            s.PutCString("\ncurr_frames:\n");
            curr_frames->Dump (&s);
            s.EOL();
#endif
            size_t curr_frame_num, prev_frame_num;
            
            for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size();
                 curr_frame_num > 0 && prev_frame_num > 0;
                 --curr_frame_num, --prev_frame_num)
            {
                const size_t curr_frame_idx = curr_frame_num-1;
                const size_t prev_frame_idx = prev_frame_num-1;
                StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]);
                StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]);

#if defined (DEBUG_STACK_FRAMES)
                s.Printf("\n\nCurr frame #%u ", curr_frame_idx);
                if (curr_frame_sp)
                    curr_frame_sp->Dump (&s, true, false);
                else
                    s.PutCString("NULL");
                s.Printf("\nPrev frame #%u ", prev_frame_idx);
                if (prev_frame_sp)
                    prev_frame_sp->Dump (&s, true, false);
                else
                    s.PutCString("NULL");
#endif

                StackFrame *curr_frame = curr_frame_sp.get();
                StackFrame *prev_frame = prev_frame_sp.get();
                
                if (curr_frame == NULL || prev_frame == NULL)
                    break;

                // Check the stack ID to make sure they are equal
                if (curr_frame->GetStackID() != prev_frame->GetStackID())
                    break;

                prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame);
                // Now copy the fixed up previous frame into the current frames
                // so the pointer doesn't change
                m_frames[curr_frame_idx] = prev_frame_sp;
                //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame);
                
#if defined (DEBUG_STACK_FRAMES)
                s.Printf("\n    Copying previous frame to current frame");
#endif
            }
            // We are done with the old stack frame list, we can release it now
            m_prev_frames_sp.reset();
        }
        
#if defined (DEBUG_STACK_FRAMES)
            s.PutCString("\n\nNew frames:\n");
            Dump (&s);
            s.EOL();
#endif
    }
    else
    {
        if (end_idx < m_concrete_frames_fetched)
            return;

        if (unwinder)
        {
            uint32_t num_frames = unwinder->GetFramesUpTo(end_idx);
            if (num_frames <= end_idx + 1)
            {
                //Done unwinding.
                m_concrete_frames_fetched = UINT32_MAX;
            }
            m_frames.resize(num_frames);
        }
    }
}

uint32_t
StackFrameList::GetNumFrames (bool can_create)
{
    Mutex::Locker locker (m_mutex);

    if (can_create)
        GetFramesUpTo (UINT32_MAX);

    uint32_t inlined_depth = GetCurrentInlinedDepth();
    if (inlined_depth == UINT32_MAX)
        return m_frames.size();
    else
        return m_frames.size() - inlined_depth;
}

void
StackFrameList::Dump (Stream *s)
{
    if (s == NULL)
        return;
    Mutex::Locker locker (m_mutex);

    const_iterator pos, begin = m_frames.begin(), end = m_frames.end();
    for (pos = begin; pos != end; ++pos)
    {
        StackFrame *frame = (*pos).get();
        s->Printf("%p: ", static_cast<void*>(frame));
        if (frame)
        {
            frame->GetStackID().Dump (s);
            frame->DumpUsingSettingsFormat (s);
        }
        else
            s->Printf("frame #%u", (uint32_t)std::distance (begin, pos));
        s->EOL();
    }
    s->EOL();
}

StackFrameSP
StackFrameList::GetFrameAtIndex (uint32_t idx)
{
    StackFrameSP frame_sp;
    Mutex::Locker locker (m_mutex);
    uint32_t original_idx = idx;
    
    uint32_t inlined_depth = GetCurrentInlinedDepth();
    if (inlined_depth != UINT32_MAX)
        idx += inlined_depth;
    
    if (idx < m_frames.size())
        frame_sp = m_frames[idx];

    if (frame_sp)
        return frame_sp;
        
    // GetFramesUpTo will fill m_frames with as many frames as you asked for,
    // if there are that many.  If there weren't then you asked for too many
    // frames.
    GetFramesUpTo (idx);
    if (idx < m_frames.size())
    {
        if (m_show_inlined_frames)
        {
            // When inline frames are enabled we actually create all the frames in GetFramesUpTo.
            frame_sp = m_frames[idx];
        }
        else
        {
            Unwind *unwinder = m_thread.GetUnwinder ();
            if (unwinder)
            {
                addr_t pc, cfa;
                if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc))
                {
                    const bool cfa_is_valid = true;
                    const bool stop_id_is_valid = false;
                    const bool is_history_frame = false;
                    frame_sp.reset (new StackFrame (m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, NULL));
                    
                    Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function;
                    if (function)
                    {
                        // When we aren't showing inline functions we always use
                        // the top most function block as the scope.
                        frame_sp->SetSymbolContextScope (&function->GetBlock(false));
                    }
                    else 
                    {
                        // Set the symbol scope from the symbol regardless if it is NULL or valid.
                        frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol);
                    }
                    SetFrameAtIndex(idx, frame_sp);
                }
            }
        }
    }
    else if (original_idx == 0)
    {
        // There should ALWAYS be a frame at index 0.  If something went wrong with the CurrentInlinedDepth such that
        // there weren't as many frames as we thought taking that into account, then reset the current inlined depth
        // and return the real zeroth frame.
        if (m_frames.size() > 0)
        {
            ResetCurrentInlinedDepth();
            frame_sp = m_frames[original_idx];
        }
        else
        {
            // Why do we have a thread with zero frames, that should not ever happen...
            if (m_thread.IsValid())
                assert ("A valid thread has no frames.");
            
        }
    }
    
    return frame_sp;
}

StackFrameSP
StackFrameList::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
{
    // First try assuming the unwind index is the same as the frame index. The 
    // unwind index is always greater than or equal to the frame index, so it
    // is a good place to start. If we have inlined frames we might have 5
    // concrete frames (frame unwind indexes go from 0-4), but we might have 15
    // frames after we make all the inlined frames. Most of the time the unwind
    // frame index (or the concrete frame index) is the same as the frame index.
    uint32_t frame_idx = unwind_idx;
    StackFrameSP frame_sp (GetFrameAtIndex (frame_idx));
    while (frame_sp)
    {
        if (frame_sp->GetFrameIndex() == unwind_idx)
            break;
        frame_sp = GetFrameAtIndex (++frame_idx);
    }
    return frame_sp;
}

static bool
CompareStackID (const StackFrameSP &stack_sp, const StackID &stack_id)
{
    return stack_sp->GetStackID() < stack_id;
}

StackFrameSP
StackFrameList::GetFrameWithStackID (const StackID &stack_id)
{
    StackFrameSP frame_sp;
    
    if (stack_id.IsValid())
    {
        Mutex::Locker locker (m_mutex);
        uint32_t frame_idx = 0;
        // Do a binary search in case the stack frame is already in our cache
        collection::const_iterator begin = m_frames.begin();
        collection::const_iterator end = m_frames.end();
        if (begin != end)
        {
            collection::const_iterator pos = std::lower_bound (begin, end, stack_id, CompareStackID);
            if (pos != end)
            {
                if ((*pos)->GetStackID() == stack_id)
                    return *pos;
            }
            
//            if (m_frames.back()->GetStackID() < stack_id)
//                frame_idx = m_frames.size();
        }
        do
        {
            frame_sp = GetFrameAtIndex (frame_idx);
            if (frame_sp && frame_sp->GetStackID() == stack_id)
                break;
            frame_idx++;
        }
        while (frame_sp);
    }
    return frame_sp;
}

bool
StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp)
{
    if (idx >= m_frames.size())
        m_frames.resize(idx + 1);
    // Make sure allocation succeeded by checking bounds again
    if (idx < m_frames.size())
    {
        m_frames[idx] = frame_sp;
        return true;
    }
    return false;   // resize failed, out of memory?
}

uint32_t
StackFrameList::GetSelectedFrameIndex () const
{
    Mutex::Locker locker (m_mutex);
    return m_selected_frame_idx;
}


uint32_t
StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame)
{
    Mutex::Locker locker (m_mutex);
    const_iterator pos;
    const_iterator begin = m_frames.begin();
    const_iterator end = m_frames.end();
    m_selected_frame_idx = 0;
    for (pos = begin; pos != end; ++pos)
    {
        if (pos->get() == frame)
        {
            m_selected_frame_idx = std::distance (begin, pos);
            uint32_t inlined_depth = GetCurrentInlinedDepth();
            if (inlined_depth != UINT32_MAX)
                m_selected_frame_idx -= inlined_depth;
            break;
        }
    }
    SetDefaultFileAndLineToSelectedFrame();
    return m_selected_frame_idx;
}

// Mark a stack frame as the current frame using the frame index
bool
StackFrameList::SetSelectedFrameByIndex (uint32_t idx)
{
    Mutex::Locker locker (m_mutex);
    StackFrameSP frame_sp (GetFrameAtIndex (idx));
    if (frame_sp)
    {
        SetSelectedFrame(frame_sp.get());
        return true;
    }
    else
        return false;
}

void
StackFrameList::SetDefaultFileAndLineToSelectedFrame()
{
    if (m_thread.GetID() == m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID())
    {
        StackFrameSP frame_sp (GetFrameAtIndex (GetSelectedFrameIndex()));
        if (frame_sp)
        {
            SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry);
            if (sc.line_entry.file)
                m_thread.CalculateTarget()->GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file, 
                                                                                            sc.line_entry.line);
        }
    }
}

// The thread has been run, reset the number stack frames to zero so we can
// determine how many frames we have lazily.
void
StackFrameList::Clear ()
{
    Mutex::Locker locker (m_mutex);
    m_frames.clear();
    m_concrete_frames_fetched = 0;
}

void
StackFrameList::InvalidateFrames (uint32_t start_idx)
{
    Mutex::Locker locker (m_mutex);
    if (m_show_inlined_frames)
    {
        Clear();
    }
    else
    {
        const size_t num_frames = m_frames.size();
        while (start_idx < num_frames)
        {
            m_frames[start_idx].reset();
            ++start_idx;
        }
    }
}

void
StackFrameList::Merge (std::unique_ptr<StackFrameList>& curr_ap, lldb::StackFrameListSP& prev_sp)
{
    Mutex::Locker curr_locker (curr_ap.get() ? &curr_ap->m_mutex : NULL);
    Mutex::Locker prev_locker (prev_sp.get() ? &prev_sp->m_mutex : NULL);

#if defined (DEBUG_STACK_FRAMES)
    StreamFile s(stdout, false);
    s.PutCString("\n\nStackFrameList::Merge():\nPrev:\n");
    if (prev_sp.get())
        prev_sp->Dump (&s);
    else
        s.PutCString ("NULL");
    s.PutCString("\nCurr:\n");
    if (curr_ap.get())
        curr_ap->Dump (&s);
    else
        s.PutCString ("NULL");
    s.EOL();
#endif

    if (curr_ap.get() == NULL || curr_ap->GetNumFrames (false) == 0)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("No current frames, leave previous frames alone...\n");
#endif
        curr_ap.release();
        return;
    }

    if (prev_sp.get() == NULL || prev_sp->GetNumFrames (false) == 0)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("No previous frames, so use current frames...\n");
#endif
        // We either don't have any previous frames, or since we have more than
        // one current frames it means we have all the frames and can safely
        // replace our previous frames.
        prev_sp.reset (curr_ap.release());
        return;
    }

    const uint32_t num_curr_frames = curr_ap->GetNumFrames (false);
    
    if (num_curr_frames > 1)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("We have more than one current frame, so use current frames...\n");
#endif
        // We have more than one current frames it means we have all the frames 
        // and can safely replace our previous frames.
        prev_sp.reset (curr_ap.release());

#if defined (DEBUG_STACK_FRAMES)
        s.PutCString("\nMerged:\n");
        prev_sp->Dump (&s);
#endif
        return;
    }

    StackFrameSP prev_frame_zero_sp(prev_sp->GetFrameAtIndex (0));
    StackFrameSP curr_frame_zero_sp(curr_ap->GetFrameAtIndex (0));
    StackID curr_stack_id (curr_frame_zero_sp->GetStackID());
    StackID prev_stack_id (prev_frame_zero_sp->GetStackID());

#if defined (DEBUG_STACK_FRAMES)
    const uint32_t num_prev_frames = prev_sp->GetNumFrames (false);
    s.Printf("\n%u previous frames with one current frame\n", num_prev_frames);
#endif

    // We have only a single current frame
    // Our previous stack frames only had a single frame as well...
    if (curr_stack_id == prev_stack_id)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.Printf("\nPrevious frame #0 is same as current frame #0, merge the cached data\n");
#endif

        curr_frame_zero_sp->UpdateCurrentFrameFromPreviousFrame (*prev_frame_zero_sp);
//        prev_frame_zero_sp->UpdatePreviousFrameFromCurrentFrame (*curr_frame_zero_sp);
//        prev_sp->SetFrameAtIndex (0, prev_frame_zero_sp);
    }
    else if (curr_stack_id < prev_stack_id)
    {
#if defined (DEBUG_STACK_FRAMES)
        s.Printf("\nCurrent frame #0 has a stack ID that is less than the previous frame #0, insert current frame zero in front of previous\n");
#endif
        prev_sp->m_frames.insert (prev_sp->m_frames.begin(), curr_frame_zero_sp);
    }
    
    curr_ap.release();

#if defined (DEBUG_STACK_FRAMES)
    s.PutCString("\nMerged:\n");
    prev_sp->Dump (&s);
#endif


}

lldb::StackFrameSP
StackFrameList::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
{
    const_iterator pos;
    const_iterator begin = m_frames.begin();
    const_iterator end = m_frames.end();
    lldb::StackFrameSP ret_sp;
    
    for (pos = begin; pos != end; ++pos)
    {
        if (pos->get() == stack_frame_ptr)
        {
            ret_sp = (*pos);
            break;
        }
    }
    return ret_sp;
}

size_t
StackFrameList::GetStatus (Stream& strm,
                           uint32_t first_frame,
                           uint32_t num_frames,
                           bool show_frame_info,
                           uint32_t num_frames_with_source,
                           const char *selected_frame_marker)
{
    size_t num_frames_displayed = 0;
    
    if (num_frames == 0)
        return 0;
    
    StackFrameSP frame_sp;
    uint32_t frame_idx = 0;
    uint32_t last_frame;
    
    // Don't let the last frame wrap around...
    if (num_frames == UINT32_MAX)
        last_frame = UINT32_MAX;
    else
        last_frame = first_frame + num_frames;
    
    StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame();
    const char *unselected_marker = NULL;
    std::string buffer;
    if (selected_frame_marker)
    {
        size_t len = strlen(selected_frame_marker);
        buffer.insert(buffer.begin(), len, ' ');
        unselected_marker = buffer.c_str();
    }
    const char *marker = NULL;
    
    for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx)
    {
        frame_sp = GetFrameAtIndex(frame_idx);
        if (frame_sp.get() == NULL)
            break;
        
        if (selected_frame_marker != NULL)
        {
            if (frame_sp == selected_frame_sp)
                marker = selected_frame_marker;
            else
                marker = unselected_marker;
        }
        
        if (!frame_sp->GetStatus (strm,
                                  show_frame_info,
                                  num_frames_with_source > (first_frame - frame_idx), marker))
            break;
        ++num_frames_displayed;
    }
    
    strm.IndentLess();
    return num_frames_displayed;
}

