|  | //===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "Plugins/Process/Utility/ThreadMemory.h" | 
|  | #include "lldb/Target/OperatingSystem.h" | 
|  | #include "lldb/Target/RegisterContext.h" | 
|  | #include "lldb/Target/Process.h" | 
|  | #include "lldb/Target/StopInfo.h" | 
|  | #include "lldb/Target/Unwind.h" | 
|  | #include "Plugins/Process/Utility/RegisterContextThreadMemory.h" | 
|  |  | 
|  | using namespace lldb; | 
|  | using namespace lldb_private; | 
|  |  | 
|  | ThreadMemory::ThreadMemory (Process &process, | 
|  | tid_t tid, | 
|  | const ValueObjectSP &thread_info_valobj_sp) : | 
|  | Thread (process, tid), | 
|  | m_backing_thread_sp (), | 
|  | m_thread_info_valobj_sp (thread_info_valobj_sp), | 
|  | m_name(), | 
|  | m_queue() | 
|  | { | 
|  | } | 
|  |  | 
|  |  | 
|  | ThreadMemory::ThreadMemory (Process &process, | 
|  | lldb::tid_t tid, | 
|  | const char *name, | 
|  | const char *queue, | 
|  | lldb::addr_t register_data_addr) : | 
|  | Thread (process, tid), | 
|  | m_backing_thread_sp (), | 
|  | m_thread_info_valobj_sp (), | 
|  | m_name(), | 
|  | m_queue(), | 
|  | m_register_data_addr (register_data_addr) | 
|  | { | 
|  | if (name) | 
|  | m_name = name; | 
|  | if (queue) | 
|  | m_queue = queue; | 
|  | } | 
|  |  | 
|  |  | 
|  | ThreadMemory::~ThreadMemory() | 
|  | { | 
|  | DestroyThread(); | 
|  | } | 
|  |  | 
|  | void | 
|  | ThreadMemory::WillResume (StateType resume_state) | 
|  | { | 
|  | if (m_backing_thread_sp) | 
|  | m_backing_thread_sp->WillResume(resume_state); | 
|  | } | 
|  |  | 
|  | void | 
|  | ThreadMemory::ClearStackFrames () | 
|  | { | 
|  | if (m_backing_thread_sp) | 
|  | m_backing_thread_sp->ClearStackFrames(); | 
|  | Thread::ClearStackFrames(); | 
|  | } | 
|  |  | 
|  | RegisterContextSP | 
|  | ThreadMemory::GetRegisterContext () | 
|  | { | 
|  | if (!m_reg_context_sp) | 
|  | m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr)); | 
|  | return m_reg_context_sp; | 
|  | } | 
|  |  | 
|  | RegisterContextSP | 
|  | ThreadMemory::CreateRegisterContextForFrame (Frame *frame) | 
|  | { | 
|  | RegisterContextSP reg_ctx_sp; | 
|  | uint32_t concrete_frame_idx = 0; | 
|  |  | 
|  | if (frame) | 
|  | concrete_frame_idx = frame->GetConcreteFrameIndex (); | 
|  |  | 
|  | if (concrete_frame_idx == 0) | 
|  | { | 
|  | reg_ctx_sp = GetRegisterContext (); | 
|  | } | 
|  | else | 
|  | { | 
|  | Unwind *unwinder = GetUnwinder (); | 
|  | if (unwinder) | 
|  | reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame); | 
|  | } | 
|  | return reg_ctx_sp; | 
|  | } | 
|  |  | 
|  | bool | 
|  | ThreadMemory::CalculateStopInfo () | 
|  | { | 
|  | if (m_backing_thread_sp) | 
|  | { | 
|  | lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopInfo()); | 
|  | if (backing_stop_info_sp) | 
|  | { | 
|  | backing_stop_info_sp->SetThread (shared_from_this()); | 
|  | SetStopInfo (backing_stop_info_sp); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | ProcessSP process_sp (GetProcess()); | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | OperatingSystem *os = process_sp->GetOperatingSystem (); | 
|  | if (os) | 
|  | { | 
|  | SetStopInfo (os->CreateThreadStopReason (this)); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void | 
|  | ThreadMemory::RefreshStateAfterStop() | 
|  | { | 
|  | if (m_backing_thread_sp) | 
|  | return m_backing_thread_sp->RefreshStateAfterStop(); | 
|  |  | 
|  | if (m_reg_context_sp) | 
|  | m_reg_context_sp->InvalidateAllRegisters(); | 
|  | } |