Commit 4497f4db authored by ussrhero's avatar ussrhero

Merge branch 'typeInfoCache' into 'dev-1.0'

Type info cache

See merge request !25
parents 5be28cda 893cd613
......@@ -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