Commit 893cd613 authored by Mikhail I. Izmestev's avatar Mikhail I. Izmestev Committed by ussrhero

Removed TypeInfo cache

The most time consuming procedure of loading type by name is findModuleBySymbol.
There are lot of other places where findModuleBySymbol used.
Also TypeInfo cache may contains invalid records after module unload.
parent 5be28cda
......@@ -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;
......
......@@ -154,7 +154,6 @@ protected:
static bool isBaseType( const std::wstring &typeName );
static bool isComplexType( const std::wstring &typeName );
static TypeInfoPtr getTypeInfoFromCache(const std::wstring &typeName );
static TypeInfoPtr getBaseTypeInfo( const std::wstring &typeName, size_t ptrSize = 0);
static TypeInfoPtr getBaseTypeInfo( const SymbolPtr &symbolScope );
......
......@@ -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;
......
......@@ -701,6 +701,10 @@ ScopePtr ModuleImp::getScope()
MEMOFFSET_64 findModuleBySymbol( const std::wstring &symbolName )
{
MEMOFFSET_64 module_base = ProcessMonitor::getModuleBaseBySymbol(symbolName);
if (module_base)
return module_base;
std::vector<MEMOFFSET_64> moduleList = getModuleBasesList();
std::vector<MEMOFFSET_64>::const_iterator it;
......@@ -711,7 +715,8 @@ MEMOFFSET_64 findModuleBySymbol( const std::wstring &symbolName )
try {
SymbolPtr typeInfo = module->getSymbolByName( symbolName );
return *it;
module_base = *it;
break;
}
catch( SymbolException& )
{}
......@@ -719,12 +724,19 @@ MEMOFFSET_64 findModuleBySymbol( const std::wstring &symbolName )
try {
TypeInfoPtr typeInfo = module->getTypeByName( symbolName );
return *it;
module_base = *it;
break;
}
catch( SymbolException& )
{}
}
if (module_base)
{
ProcessMonitor::insertModuleBaseBySymbol(symbolName, module_base);
return module_base;
}
std::wstringstream sstr;
sstr << L"failed to find module for symbol: " << symbolName;
throw SymbolException( sstr.str() );
......
......@@ -25,8 +25,11 @@ public:
void insertModule( ModulePtr& module);
void removeModule(MEMOFFSET_64 offset );
TypeInfoPtr getTypeInfo(const std::wstring& name);
void insertTypeInfo(const TypeInfoPtr& typeInfo);
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);
......@@ -41,10 +44,14 @@ private:
ModuleMap m_moduleMap;
boost::recursive_mutex m_moduleLock;
typedef std::map<std::wstring, TypeInfoPtr> TypeInfoMap;
TypeInfoMap m_typeInfoMap;
boost::recursive_mutex m_typeInfoLock;
typedef std::map<std::wstring, MEMOFFSET_64> SymbolMap;
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;
......@@ -89,8 +96,8 @@ public:
ModulePtr getModule( MEMOFFSET_64 offset, PROCESS_DEBUG_ID id );
void insertModule( ModulePtr& module, PROCESS_DEBUG_ID id );
TypeInfoPtr getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id = -1);
void insertTypeInfo(const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id = -1);
MEMOFFSET_64 getModuleBaseBySymbol(const std::wstring& sym, PROCESS_DEBUG_ID id);
void insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base, PROCESS_DEBUG_ID id);
void registerEventsCallback(DebugEventsCallback *callback);
void removeEventsCallback(DebugEventsCallback *callback);
......@@ -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);
......@@ -347,22 +377,22 @@ void ProcessMonitor::insertModule( ModulePtr& module, PROCESS_DEBUG_ID id )
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessMonitor::getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id)
MEMOFFSET_64 ProcessMonitor::getModuleBaseBySymbol(const std::wstring& sym, PROCESS_DEBUG_ID id)
{
if (id == -1)
id = getCurrentProcessId();
return g_procmon->getTypeInfo(name, id);
return g_procmon->getModuleBaseBySymbol(sym, id);
}
///////////////////////////////////////////////////////////////////////////////
void ProcessMonitor::insertTypeInfo(const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
void ProcessMonitor::insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base, PROCESS_DEBUG_ID id)
{
if (id == -1)
id = getCurrentProcessId();
return g_procmon->insertTypeInfo(typeInfo, id);
return g_procmon->insertModuleBaseBySymbol(sym, module_base, id);
}
///////////////////////////////////////////////////////////////////////////////
......@@ -716,22 +746,42 @@ void ProcessMonitorImpl::insertModule( ModulePtr& module, PROCESS_DEBUG_ID id )
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessMonitorImpl::getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id)
MEMOFFSET_64 ProcessMonitorImpl::getModuleBaseBySymbol(const std::wstring& sym, PROCESS_DEBUG_ID id)
{
ProcessInfoPtr processInfo = getProcess(id);
if ( processInfo )
return processInfo->getTypeInfo(name);
if (processInfo)
return processInfo->getModuleBaseBySymbol(sym);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void ProcessMonitorImpl::insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base, PROCESS_DEBUG_ID id)
{
ProcessInfoPtr processInfo = getProcess(id);
if (processInfo)
return processInfo->insertModuleBaseBySymbol(sym, module_base);
}
///////////////////////////////////////////////////////////////////////////////
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 TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
void ProcessMonitorImpl::insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id)
{
ProcessInfoPtr processInfo = getProcess(id);
if (processInfo)
return processInfo->insertTypeInfo(typeInfo);
return processInfo->insertTypeInfo(sym, typeInfo);
}
///////////////////////////////////////////////////////////////////////////////
......@@ -826,19 +876,78 @@ void ProcessInfo::insertModule( ModulePtr& module)
void ProcessInfo::removeModule(MEMOFFSET_64 offset )
{
boost::recursive_mutex::scoped_lock l(m_moduleLock);
m_moduleMap.erase(offset);
ModulePtr module;
{
boost::recursive_mutex::scoped_lock l(m_moduleLock);
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
{
boost::recursive_mutex::scoped_lock l(m_symbolLock);
SymbolMap::iterator it = m_symbolMap.begin();
while (it != m_symbolMap.end())
{
if(it->second == offset)
it = m_symbolMap.erase(it);
else
++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;
}
}
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ProcessInfo::getTypeInfo(const std::wstring& name)
MEMOFFSET_64 ProcessInfo::getModuleBaseBySymbol(const std::wstring& sym)
{
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
boost::recursive_mutex::scoped_lock l(m_symbolLock);
SymbolMap::iterator it = m_symbolMap.find(sym);
if(it != m_symbolMap.end())
return it->second;
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void ProcessInfo::insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base)
{
boost::recursive_mutex::scoped_lock l(m_symbolLock);
m_symbolMap[sym] = module_base;
}
TypeInfoMap::iterator it = m_typeInfoMap.find(name);
///////////////////////////////////////////////////////////////////////////////
if (it != m_typeInfoMap.end())
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();
......@@ -846,11 +955,15 @@ TypeInfoPtr ProcessInfo::getTypeInfo(const std::wstring& name)
///////////////////////////////////////////////////////////////////////////////
void ProcessInfo::insertTypeInfo(const TypeInfoPtr& typeInfo)
void ProcessInfo::insertTypeInfo(const SymbolPtr& sym, const TypeInfoPtr& typeInfo)
{
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
TypeInfoMap::key_type key{ sym->getScopeName(), sym->getSymIndexId() };
m_typeInfoMap.insert(std::make_pair(typeInfo->getName(), typeInfo));
if (key.second != Symbol::InvalidId)
{
boost::recursive_mutex::scoped_lock l(m_typeInfoLock);
m_typeInfoMap[key] = typeInfo;
}
}
///////////////////////////////////////////////////////////////////////////////
......
......@@ -48,6 +48,9 @@ public: // module manipulation
static ModulePtr getModule( MEMOFFSET_64 offset, PROCESS_DEBUG_ID id = -1 );
static void insertModule( ModulePtr& module, PROCESS_DEBUG_ID id = -1 );
static MEMOFFSET_64 getModuleBaseBySymbol(const std::wstring& sym, PROCESS_DEBUG_ID id = -1);
static void insertModuleBaseBySymbol(const std::wstring& sym, MEMOFFSET_64 module_base, PROCESS_DEBUG_ID id = -1);
public: //breakpoint callbacks
static void registerBreakpoint( const BreakpointPtr& breakpoint, PROCESS_DEBUG_ID id = -1 );
......@@ -57,10 +60,9 @@ public: //callbacks
static void registerEventsCallback(DebugEventsCallback *callback);
static void removeEventsCallback(DebugEventsCallback *callback);
public: //
static TypeInfoPtr getTypeInfo(const std::wstring& name, PROCESS_DEBUG_ID id = -1);
static void insertTypeInfo( const TypeInfoPtr& typeInfo, PROCESS_DEBUG_ID id = -1);
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);
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -284,12 +284,18 @@ TypeInfoPtr loadType( const std::wstring &typeName )
splitSymName( typeName, moduleName, symName );
ModulePtr module;
if ( moduleName.empty() )
{
return TypeInfo::getTypeInfoFromCache(symName);
MEMOFFSET_64 moduleOffset = findModuleBySymbol(symName);
module = loadModule(moduleOffset);
}
else
{
module = loadModule(moduleName);
}
ModulePtr module = loadModule(moduleName);
SymbolPtr symbolScope = module->getSymbolScope();
......@@ -326,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 )
{
......@@ -350,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() ) );
......@@ -404,6 +417,7 @@ TypeInfoPtr loadType( const SymbolPtr &symbol )
//if ( ptr )
// ptr->m_ptrSize = getTypePointerSize(typeSym);
ProcessMonitor::insertTypeInfo(symbol, ptr);
return ptr;
}
......@@ -751,23 +765,6 @@ TypeInfoPtr TypeInfo::getRecursiveComplexType( const std::wstring &typeName, Typ
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeInfo::getTypeInfoFromCache(const std::wstring &typeName)
{
TypeInfoPtr cachedType = ProcessMonitor::getTypeInfo(typeName);
if (cachedType)
return cachedType;
MEMOFFSET_64 moduleOffset = findModuleBySymbol(typeName);
TypeInfoPtr typeInfo = loadModule(moduleOffset)->getTypeByName(typeName);;
ProcessMonitor::insertTypeInfo(typeInfo);
return typeInfo;
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeInfoImp::ptrTo( size_t ptrSize )
{
return TypeInfoPtr( new TypeInfoPointer( shared_from_this(), ptrSize ? ptrSize : getPtrSize() ) );
......
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