Instead of having an UnwindTable own a single assembly profiler,

and sharing it with all of its FuncUnwinders, have each FuncUnwinder
create an AssemblyProfiler on demand as needed.  I was worried that
the cost of creating the llvm disassemblers would be high for this
approach but it's not supposed to be an expensive operation, and it
means we don't need to add locks around this section of code.
<rdar://problem/16992332> 

llvm-svn: 209493
This commit is contained in:
Jason Molenda 2014-05-23 01:48:10 +00:00
parent 23a285d2d6
commit ab35aa92da
4 changed files with 40 additions and 24 deletions

View File

@ -31,7 +31,7 @@ public:
// instructions are finished for migrating breakpoints past the // instructions are finished for migrating breakpoints past the
// stack frame setup instructions when we don't have line table information. // stack frame setup instructions when we don't have line table information.
FuncUnwinders (lldb_private::UnwindTable& unwind_table, const lldb::UnwindAssemblySP& assembly_profiler, AddressRange range); FuncUnwinders (lldb_private::UnwindTable& unwind_table, AddressRange range);
~FuncUnwinders (); ~FuncUnwinders ();
@ -76,8 +76,11 @@ public:
InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread); InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread);
private: private:
lldb::UnwindAssemblySP
GetUnwindAssemblyProfiler ();
UnwindTable& m_unwind_table; UnwindTable& m_unwind_table;
lldb::UnwindAssemblySP m_assembly_profiler;
AddressRange m_range; AddressRange m_range;
Mutex m_mutex; Mutex m_mutex;

View File

@ -13,7 +13,7 @@
#include <map> #include <map>
#include "lldb/lldb-private.h" #include "lldb/lldb-private.h"
namespace lldb_private { namespace lldb_private {
@ -42,6 +42,9 @@ public:
lldb::FuncUnwindersSP lldb::FuncUnwindersSP
GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
bool
GetArchitecture (lldb_private::ArchSpec &arch);
private: private:
void void
Dump (Stream &s); Dump (Stream &s);
@ -57,8 +60,6 @@ private:
bool m_initialized; // delay some initialization until ObjectFile is set up bool m_initialized; // delay some initialization until ObjectFile is set up
lldb::UnwindAssemblySP m_assembly_profiler;
DWARFCallFrameInfo* m_eh_frame; DWARFCallFrameInfo* m_eh_frame;
DISALLOW_COPY_AND_ASSIGN (UnwindTable); DISALLOW_COPY_AND_ASSIGN (UnwindTable);

View File

@ -28,11 +28,9 @@ using namespace lldb_private;
FuncUnwinders::FuncUnwinders FuncUnwinders::FuncUnwinders
( (
UnwindTable& unwind_table, UnwindTable& unwind_table,
const lldb::UnwindAssemblySP& assembly_profiler,
AddressRange range AddressRange range
) : ) :
m_unwind_table(unwind_table), m_unwind_table(unwind_table),
m_assembly_profiler(assembly_profiler),
m_range(range), m_range(range),
m_mutex (Mutex::eMutexTypeNormal), m_mutex (Mutex::eMutexTypeNormal),
m_unwind_plan_call_site_sp (), m_unwind_plan_call_site_sp (),
@ -113,11 +111,11 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
Mutex::Locker locker (m_mutex); Mutex::Locker locker (m_mutex);
if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == nullptr) if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == nullptr)
{ {
m_tried_unwind_at_non_call_site = true; UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
if (m_assembly_profiler) if (assembly_profiler_sp)
{ {
m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp)) if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp))
m_unwind_plan_non_call_site_sp.reset(); m_unwind_plan_non_call_site_sp.reset();
} }
} }
@ -143,10 +141,11 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == nullptr) if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == nullptr)
{ {
m_tried_unwind_fast = true; m_tried_unwind_fast = true;
if (m_assembly_profiler) UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
if (assembly_profiler_sp)
{ {
m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp)) if (!assembly_profiler_sp->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp))
m_unwind_plan_fast_sp.reset(); m_unwind_plan_fast_sp.reset();
} }
} }
@ -232,8 +231,10 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
if (m_first_non_prologue_insn.IsValid()) if (m_first_non_prologue_insn.IsValid())
return m_first_non_prologue_insn; return m_first_non_prologue_insn;
ExecutionContext exe_ctx (target.shared_from_this(), false); ExecutionContext exe_ctx (target.shared_from_this(), false);
if (m_assembly_profiler) UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
m_assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn); if (assembly_profiler_sp)
if (assembly_profiler_sp)
assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
return m_first_non_prologue_insn; return m_first_non_prologue_insn;
} }
@ -252,3 +253,15 @@ FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
m_unwind_plan_call_site_sp = arch_default; m_unwind_plan_call_site_sp = arch_default;
} }
} }
lldb::UnwindAssemblySP
FuncUnwinders::GetUnwindAssemblyProfiler ()
{
UnwindAssemblySP assembly_profiler_sp;
ArchSpec arch;
if (m_unwind_table.GetArchitecture (arch))
{
assembly_profiler_sp = UnwindAssembly::FindPlugin (arch);
}
return assembly_profiler_sp;
}

View File

@ -17,7 +17,6 @@
#include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Target/UnwindAssembly.h"
// There is one UnwindTable object per ObjectFile. // There is one UnwindTable object per ObjectFile.
// It contains a list of Unwind objects -- one per function, populated lazily -- for the ObjectFile. // It contains a list of Unwind objects -- one per function, populated lazily -- for the ObjectFile.
@ -30,7 +29,6 @@ UnwindTable::UnwindTable (ObjectFile& objfile) :
m_object_file (objfile), m_object_file (objfile),
m_unwinds (), m_unwinds (),
m_initialized (false), m_initialized (false),
m_assembly_profiler (nullptr),
m_eh_frame (nullptr) m_eh_frame (nullptr)
{ {
} }
@ -54,12 +52,7 @@ UnwindTable::Initialize ()
} }
} }
ArchSpec arch; m_initialized = true;
if (m_object_file.GetArchitecture (arch))
{
m_assembly_profiler = UnwindAssembly::FindPlugin (arch);
m_initialized = true;
}
} }
UnwindTable::~UnwindTable () UnwindTable::~UnwindTable ()
@ -100,7 +93,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
} }
} }
FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range)); FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp)); m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp));
// StreamFile s(stdout, false); // StreamFile s(stdout, false);
// Dump (s); // Dump (s);
@ -127,7 +120,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, Sym
} }
} }
FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range)); FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
return func_unwinder_sp; return func_unwinder_sp;
} }
@ -151,3 +144,9 @@ UnwindTable::GetEHFrameInfo ()
Initialize(); Initialize();
return m_eh_frame; return m_eh_frame;
} }
bool
UnwindTable::GetArchitecture (lldb_private::ArchSpec &arch)
{
return m_object_file.GetArchitecture (arch);
}