diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index a7c7ffb016..17fcba82ec 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -83,11 +83,18 @@ std::unordered_map progressMap; struct ViewSpecificMutexes { std::mutex viewOperationsThatInfluenceMetadataMutex; - std::mutex typeLibraryLookupAndApplicationMutex; }; static std::unordered_map viewSpecificMutexes; +// TODO: I believe this leaks memory due to no cleanup when a view is closed +struct ViewSpecificCaches { + std::map> typeLibraryCache; + std::mutex typeLibraryCacheMutex; +}; + +static std::unordered_map viewSpecificCaches; + std::string base_name(std::string const& path) { @@ -1785,21 +1792,27 @@ bool SharedCache::LoadImageWithInstallName(std::string installName) return false; } - std::unique_lock typelibLock(viewSpecificMutexes[m_dscView->GetFile()->GetSessionId()].typeLibraryLookupAndApplicationMutex); - auto typeLib = m_dscView->GetTypeLibrary(header.installName); - - if (!typeLib) + Ref typeLib; + std::unique_lock typeLibraryCacheLock(viewSpecificCaches[m_dscView->GetFile()->GetSessionId()].typeLibraryCacheMutex); + auto typeLibraryCache = viewSpecificCaches[m_dscView->GetFile()->GetSessionId()].typeLibraryCache; + if (auto it = typeLibraryCache.find(header.installName); it != typeLibraryCache.end()) { + typeLib = it->second; + } + else { - auto typeLibs = m_dscView->GetDefaultPlatform()->GetTypeLibrariesByName(header.installName); - if (!typeLibs.empty()) + typeLib = m_dscView->GetTypeLibrary(header.installName); + if (!typeLib) { - typeLib = typeLibs[0]; - m_dscView->AddTypeLibrary(typeLib); - m_logger->LogInfo("shared-cache: adding type library for '%s': %s (%s)", - targetImage->installName.c_str(), typeLib->GetName().c_str(), typeLib->GetGuid().c_str()); + auto typeLibs = m_dscView->GetDefaultPlatform()->GetTypeLibrariesByName(header.installName); + if (!typeLibs.empty()) + { + typeLib = typeLibs[0]; + typeLibraryCache[header.installName] = typeLib; + m_dscView->AddTypeLibrary(typeLib); + } } } - typelibLock.unlock(); + typeLibraryCacheLock.unlock(); SaveToDSCView(); @@ -2885,18 +2898,29 @@ void SharedCache::FindSymbolAtAddrAndApplyToAddr(uint64_t symbolLocation, uint64 } auto exportList = SharedCache::ParseExportTrie(mapping, *header); std::vector>> exportMapping; - std::unique_lock lock(viewSpecificMutexes[m_dscView->GetFile()->GetSessionId()].typeLibraryLookupAndApplicationMutex); - auto typeLib = m_dscView->GetTypeLibrary(header->installName); - if (!typeLib) + + Ref typeLib; + std::unique_lock typeLibraryCacheLock(viewSpecificCaches[m_dscView->GetFile()->GetSessionId()].typeLibraryCacheMutex); + auto typeLibraryCache = viewSpecificCaches[m_dscView->GetFile()->GetSessionId()].typeLibraryCache; + if (auto it = typeLibraryCache.find(header->installName); it != typeLibraryCache.end()) { + typeLib = it->second; + } + else { - auto typeLibs = m_dscView->GetDefaultPlatform()->GetTypeLibrariesByName(header->installName); - if (!typeLibs.empty()) + typeLib = m_dscView->GetTypeLibrary(header->installName); + if (!typeLib) { - typeLib = typeLibs[0]; - m_dscView->AddTypeLibrary(typeLib); + auto typeLibs = m_dscView->GetDefaultPlatform()->GetTypeLibrariesByName(header->installName); + if (!typeLibs.empty()) + { + typeLib = typeLibs[0]; + typeLibraryCache[header->installName] = typeLib; + m_dscView->AddTypeLibrary(typeLib); + } } } - lock.unlock(); + typeLibraryCacheLock.unlock(); + id = m_dscView->BeginUndoActions(); m_dscView->BeginBulkModifySymbols(); for (const auto& sym : exportList)