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
// 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 ();
@ -76,8 +76,11 @@ public:
InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread);
private:
lldb::UnwindAssemblySP
GetUnwindAssemblyProfiler ();
UnwindTable& m_unwind_table;
lldb::UnwindAssemblySP m_assembly_profiler;
AddressRange m_range;
Mutex m_mutex;

View File

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

View File

@ -28,11 +28,9 @@ using namespace lldb_private;
FuncUnwinders::FuncUnwinders
(
UnwindTable& unwind_table,
const lldb::UnwindAssemblySP& assembly_profiler,
AddressRange range
) :
m_unwind_table(unwind_table),
m_assembly_profiler(assembly_profiler),
m_range(range),
m_mutex (Mutex::eMutexTypeNormal),
m_unwind_plan_call_site_sp (),
@ -113,11 +111,11 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
Mutex::Locker locker (m_mutex);
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;
if (m_assembly_profiler)
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
if (assembly_profiler_sp)
{
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();
}
}
@ -143,10 +141,11 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == nullptr)
{
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));
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();
}
}
@ -232,8 +231,10 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
if (m_first_non_prologue_insn.IsValid())
return m_first_non_prologue_insn;
ExecutionContext exe_ctx (target.shared_from_this(), false);
if (m_assembly_profiler)
m_assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
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;
}
@ -252,3 +253,15 @@ FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
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/SymbolContext.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Target/UnwindAssembly.h"
// There is one UnwindTable object per 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_unwinds (),
m_initialized (false),
m_assembly_profiler (nullptr),
m_eh_frame (nullptr)
{
}
@ -54,12 +52,7 @@ UnwindTable::Initialize ()
}
}
ArchSpec arch;
if (m_object_file.GetArchitecture (arch))
{
m_assembly_profiler = UnwindAssembly::FindPlugin (arch);
m_initialized = true;
}
m_initialized = true;
}
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));
// StreamFile s(stdout, false);
// 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;
}
@ -151,3 +144,9 @@ UnwindTable::GetEHFrameInfo ()
Initialize();
return m_eh_frame;
}
bool
UnwindTable::GetArchitecture (lldb_private::ArchSpec &arch)
{
return m_object_file.GetArchitecture (arch);
}