Commit 952c9edf authored by Mikhail I. Izmestev's avatar Mikhail I. Izmestev
Browse files

Add TypeInfo cache

You should avoid to keep TypeInfoPtr inside of cached instances, to prevent loop
references.
parent 0ee93613
......@@ -171,7 +171,10 @@ enum CallingConventionType
class Symbol {
public:
typedef unsigned long SymIndexId;
static const SymIndexId InvalidId = -1;
virtual SymIndexId getSymIndexId() { return InvalidId; }
virtual SymbolPtrList findChildren( unsigned long symTag, const std::wstring &name = L"", bool caseSensitive = false ) = 0;
virtual SymbolPtrList findChildrenByRVA(unsigned long symTag, unsigned long rva) = 0;
virtual unsigned long getBaseType() = 0;
......
......@@ -200,6 +200,18 @@ SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol, const std::wstring& _
//////////////////////////////////////////////////////////////////////////////////
Symbol::SymIndexId DiaSymbol::getSymIndexId()
{
SymIndexId id;
HRESULT hres = m_symbol->get_symIndexId(&id);
if(S_OK == hres)
return id;
return Symbol::getSymIndexId();
}
//////////////////////////////////////////////////////////////////////////////////
SymbolPtrList DiaSymbol::findChildren(
ULONG symTag,
const std::wstring &name,
......
......@@ -59,6 +59,8 @@ public:
static SymbolPtr fromGlobalScope( IDiaSymbol *_symbol, const std::wstring &_scope );
SymIndexId getSymIndexId() override;
SymbolPtr getChildByName(const std::wstring &_name ) override;
ULONG getRva() override;
......
......@@ -28,6 +28,9 @@ public:
MEMOFFSET_64 getModuleBaseBySymbol(const std::wstring& sym);
void insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base);
TypeInfoPtr getTypeInfo(const SymbolPtr& sym);
void insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo);
void insertBreakpoint(const BreakpointPtr& breakpoint);
void removeBreakpoint(const BreakpointPtr& breakpoint);
......@@ -45,6 +48,10 @@ private:
SymbolMap m_symbolMap;
boost::recursive_mutex m_symbolLock;
typedef std::map<std::pair<std::wstring, Symbol::SymIndexId>, TypeInfoPtr> TypeInfoMap;
TypeInfoMap m_typeInfoMap;
boost::recursive_mutex m_typeInfoLock;
typedef std::map<BREAKPOINT_ID, BreakpointPtr> BreakpointIdMap;
BreakpointIdMap m_breakpointMap;
boost::recursive_mutex m_breakpointLock;
......@@ -98,6 +105,9 @@ public:
void registerBreakpoint( const BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id = -1 );
void removeBreakpoint( const BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id = -1 );
TypeInfoPtr getTypeInfo(const SymbolPtr& sym, PROCESS_DEBUG_ID id = -1);
void insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id = -1);
private:
ProcessInfoPtr getProcess( PROCESS_DEBUG_ID id );
......@@ -194,6 +204,26 @@ void ProcessMonitor::removeBreakpoint( const BreakpointPtr& breakpoint, PROCESS_
/////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessMonitor::getTypeInfo(const SymbolPtr& sym, PROCESS_DEBUG_ID id)
{
if (id == -1)
id = getCurrentProcessId();
return g_procmon->getTypeInfo(sym, id);
}
/////////////////////////////////////////////////////////////////////////////
void ProcessMonitor::insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
{
if (id == -1)
id = getCurrentProcessId();
return g_procmon->insertTypeInfo(sym, typeInfo, id);
}
/////////////////////////////////////////////////////////////////////////////
DebugCallbackResult ProcessMonitor::processStart(PROCESS_DEBUG_ID id)
{
return g_procmon->processStart(id);
......@@ -736,6 +766,26 @@ void ProcessMonitorImpl::insertModuleBaseBySymbol(const std::wstring& sym, MEMOF
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessMonitorImpl::getTypeInfo(const SymbolPtr& sym, PROCESS_DEBUG_ID id)
{
ProcessInfoPtr processInfo = getProcess(id);
if (processInfo)
return processInfo->getTypeInfo(sym);
return TypeInfoPtr();
}
///////////////////////////////////////////////////////////////////////////////
void ProcessMonitorImpl::insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
{
ProcessInfoPtr processInfo = getProcess(id);
if (processInfo)
return processInfo->insertTypeInfo(sym, typeInfo);
}
///////////////////////////////////////////////////////////////////////////////
ProcessInfoPtr ProcessMonitorImpl::getProcess( PROCESS_DEBUG_ID id )
{
boost::recursive_mutex::scoped_lock l(m_lock);
......@@ -826,9 +876,16 @@ void ProcessInfo::insertModule( ModulePtr& module)
void ProcessInfo::removeModule(MEMOFFSET_64 offset )
{
ModulePtr module;
{
boost::recursive_mutex::scoped_lock l(m_moduleLock);
m_moduleMap.erase(offset);
ModuleMap::iterator it = m_moduleMap.find(offset);
if(it != m_moduleMap.end())
{
module = it->second;
m_moduleMap.erase(it);
}
}
// clear symbol cache for this module
......@@ -843,6 +900,21 @@ void ProcessInfo::removeModule(MEMOFFSET_64 offset )
++it;
}
}
// clear TypeInfo cache for this module
if(module)
{
std::wstring scope = module->getSymbolScope()->getScopeName();
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
TypeInfoMap::iterator it = m_typeInfoMap.begin();
while (it != m_typeInfoMap.end())
{
if (it->first.first == scope)
it = m_typeInfoMap.erase(it);
else
++it;
}
}
}
///////////////////////////////////////////////////////////////////////////////
......@@ -868,6 +940,34 @@ void ProcessInfo::insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessInfo::getTypeInfo(const SymbolPtr& sym)
{
TypeInfoMap::key_type key{ sym->getScopeName(), sym->getSymIndexId() };
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
TypeInfoMap::iterator it = m_typeInfoMap.find(key);
if(it != m_typeInfoMap.end())
return it->second;
return TypeInfoPtr();
}
///////////////////////////////////////////////////////////////////////////////
void ProcessInfo::insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo)
{
TypeInfoMap::key_type key{ sym->getScopeName(), sym->getSymIndexId() };
if (key.second != Symbol::InvalidId)
{
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
m_typeInfoMap[key] = typeInfo;
}
}
///////////////////////////////////////////////////////////////////////////////
void ProcessInfo::insertBreakpoint(const BreakpointPtr& breakpoint)
{
boost::recursive_mutex::scoped_lock l(m_breakpointLock);
......
......@@ -59,6 +59,10 @@ public: //breakpoint callbacks
public: //callbacks
static void registerEventsCallback(DebugEventsCallback *callback);
static void removeEventsCallback(DebugEventsCallback *callback);
public: // TypeInfo cache
static TypeInfoPtr getTypeInfo(const SymbolPtr& sym, PROCESS_DEBUG_ID id = -1);
static void insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id = -1);
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -332,7 +332,9 @@ TypeInfoPtr loadType( const SymbolPtr &symbolScope, const std::wstring &symbolNa
TypeInfoPtr loadType( const SymbolPtr &symbol )
{
unsigned long symTag = symbol->getSymTag();
TypeInfoPtr ptr;
TypeInfoPtr ptr = ProcessMonitor::getTypeInfo(symbol);
if (ptr)
return ptr;
switch( symTag )
{
......@@ -356,20 +358,25 @@ TypeInfoPtr loadType( const SymbolPtr &symbol )
break;
}
return loadType( symbol->getType() );
ptr = loadType(symbol->getType());
break;
case SymTagBaseType:
return TypeInfo::getBaseTypeInfo( symbol );
ptr = TypeInfo::getBaseTypeInfo(symbol);
break;
case SymTagUDT:
case SymTagBaseClass:
return TypeInfoPtr( new TypeInfoUdt( symbol ) );
ptr = TypeInfoPtr(new TypeInfoUdt(symbol));
break;
case SymTagArrayType:
return TypeInfoPtr( new TypeInfoSymbolArray( symbol ) );
ptr = TypeInfoPtr(new TypeInfoSymbolArray(symbol));
break;
case SymTagPointerType:
return TypeInfoPtr( new TypeInfoSymbolPointer( symbol ) );
ptr = TypeInfoPtr(new TypeInfoSymbolPointer(symbol));
break;
case SymTagVTable:
ptr = TypeInfoPtr( new TypeInfoSymbolPointer( symbol->getType() ) );
......@@ -410,6 +417,7 @@ TypeInfoPtr loadType( const SymbolPtr &symbol )
//if ( ptr )
// ptr->m_ptrSize = getTypePointerSize(typeSym);
ProcessMonitor::insertTypeInfo(symbol, ptr);
return ptr;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment