From 27eb30dcfcb5f897aed7c7b128e7c50a2020a6a1 Mon Sep 17 00:00:00 2001 From: kat Date: Mon, 10 Feb 2025 13:46:15 -0500 Subject: [SharedCache] Optimizations regarding stl container usage in SharedCache.cpp --- view/sharedcache/core/SharedCache.cpp | 128 +++++++++++++++++----------------- 1 file changed, 63 insertions(+), 65 deletions(-) (limited to 'view/sharedcache/core/SharedCache.cpp') diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 83248d34..062031c6 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -349,6 +349,7 @@ void SharedCache::PerformInitialLoad() if (primaryCacheHeader.branchPoolsCount) { std::vector addresses; + addresses.reserve(primaryCacheHeader.branchPoolsCount); for (size_t i = 0; i < primaryCacheHeader.branchPoolsCount; i++) { addresses.push_back(baseFile->ReadULong(primaryCacheHeader.branchPoolsOffset + (i * m_dscView->GetAddressSize()))); @@ -410,7 +411,6 @@ void SharedCache::PerformInitialLoad() if (primaryCacheHeader.branchPoolsCount) { - std::vector pool {}; for (size_t i = 0; i < primaryCacheHeader.branchPoolsCount; i++) { MutableState().imageStarts["dyld_shared_cache_branch_islands_" + std::to_string(i)] = @@ -424,6 +424,7 @@ void SharedCache::PerformInitialLoad() dyld_subcache_entry2 _entry {}; std::vector subCacheEntries; + subCacheEntries.reserve(subCacheCount); for (size_t i = 0; i < subCacheCount; i++) { baseFile->Read(&_entry, primaryCacheHeader.subCacheArrayOffset + (i * sizeof(dyld_subcache_entry2)), @@ -514,7 +515,6 @@ void SharedCache::PerformInitialLoad() if (primaryCacheHeader.branchPoolsCount) { - std::vector pool {}; for (size_t i = 0; i < primaryCacheHeader.branchPoolsCount; i++) { MutableState().imageStarts["dyld_shared_cache_branch_islands_" + std::to_string(i)] = @@ -635,7 +635,6 @@ void SharedCache::PerformInitialLoad() if (primaryCacheHeader.branchPoolsCount) { - std::vector pool {}; for (size_t i = 0; i < primaryCacheHeader.branchPoolsCount; i++) { MutableState().imageStarts["dyld_shared_cache_branch_islands_" + std::to_string(i)] = @@ -651,6 +650,7 @@ void SharedCache::PerformInitialLoad() dyld_subcache_entry2 _entry {}; std::vector subCacheEntries; + subCacheEntries.reserve(subCacheCount); for (size_t i = 0; i < subCacheCount; i++) { baseFile->Read(&_entry, primaryCacheHeader.subCacheArrayOffset + (i * sizeof(dyld_subcache_entry2)), @@ -1037,7 +1037,6 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptr> rewrites; dyld_cache_header baseHeader; file->Read(&baseHeader, 0, sizeof(dyld_cache_header)); @@ -1195,7 +1194,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrWritePointer(loc, value); } catch (MappingReadException& ex) { @@ -1273,7 +1272,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrWritePointer(loc, value); } else { @@ -1281,7 +1280,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrWritePointer(loc, value); } } catch (MappingReadException& ex) @@ -1326,12 +1325,12 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrWritePointer(loc, value); } else { uint64_t value = mapping.slideInfoV5.value_add + slideInfo.regular.runtimeOffset; - rewrites.emplace_back(loc, value); + file->WritePointer(loc, value); } } catch (MappingReadException& ex) @@ -1348,33 +1347,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrWritePointer(loc, value); -#ifdef SLIDEINFO_DEBUG_TAGS - uint64_t vmAddr = 0; - { - for (uint64_t off = baseHeader.mappingOffset; off < baseHeader.mappingOffset + baseHeader.mappingCount * sizeof(dyld_cache_mapping_info); off += sizeof(dyld_cache_mapping_info)) - { - dyld_cache_mapping_info mapping; - file->Read(&mapping, off, sizeof(dyld_cache_mapping_info)); - if (mapping.fileOffset <= loc && loc < mapping.fileOffset + mapping.size) - { - vmAddr = mapping.address + (loc - mapping.fileOffset); - break; - } - } - } - Ref type = m_dscView->GetTagType("slideinfo"); - if (!type) - { - m_dscView->AddTagType(new TagType(m_dscView, "slideinfo", "\xF0\x9F\x9A\x9E")); - type = m_dscView->GetTagType("slideinfo"); - } - m_dscView->AddAutoDataTag(vmAddr, new Tag(type, "0x" + to_hex_string(file->ReadULong(loc)) + " => 0x" + to_hex_string(value))); -#endif - } - m_logger->LogDebug("Applied slide info for %s (0x%llx rewrites)", file->Path().c_str(), rewrites.size()); + // m_logger->LogDebug("Applied slide info for %s (0x%llx rewrites)", file->Path().c_str(), rewrites.size()); file->SetSlideInfoWasApplied(true); } @@ -1808,6 +1781,7 @@ bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObj reader.Seek(targetImage->headerLocation); std::vector regionsToLoad; + regionsToLoad.reserve(targetImage->regions.size()); for (auto& region : targetImage->regions) { @@ -1852,13 +1826,7 @@ bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObj return false; } - std::vector regions; - for (auto& region : regionsToLoad) - { - regions.push_back(region); - } - - SharedCache::InitializeHeader(m_dscView, vm.get(), *h, regions); + SharedCache::InitializeHeader(m_dscView, vm.get(), *h, regionsToLoad); if (!skipObjC) { @@ -2594,6 +2562,8 @@ void SharedCache::InitializeHeader( memset(&sym, 0, sizeof(sym)); auto N_TYPE = 0xE; // idk std::vector>> symbolInfos; + symbolInfos.reserve(header.symtab.nsyms); + for (size_t i = 0; i < header.symtab.nsyms; i++) { reader->Read(&sym, header.symtab.symoff + i * sizeof(nlist_64), sizeof(nlist_64)); @@ -2658,9 +2628,9 @@ void SharedCache::InitializeHeader( } else view->DefineAutoSymbol(symbolObj); - symbolInfos.push_back({sym.n_value, {type, symbol}}); + symbolInfos.emplace_back(sym.n_value, std::make_pair(type, std::move(symbol))); } - MutableState().symbolInfos[header.textBase] = symbolInfos; + MutableState().symbolInfos[header.textBase] = std::move(symbolInfos); } if (header.exportTriePresent && header.linkeditPresent && vm->AddressIsMapped(header.linkeditSegment.vmaddr)) @@ -2797,7 +2767,6 @@ std::vector> SharedCache::ParseExportTrie(std::shared_ptr> symbols; auto [begin, end] = linkeditFile->ReadSpan(header.exportTrie.dataoff, header.exportTrie.datasize); ReadExportNode(symbols, header, begin, end, begin, header.textBase, ""); @@ -2821,7 +2790,6 @@ std::shared_ptr>> SharedCache::GetExpor } else { - // TODO does this have to be a functor? can't we just pass the accessor? if not, why? std::shared_ptr linkeditFile = provideLinkeditFile(); if (!linkeditFile) { @@ -2830,11 +2798,12 @@ std::shared_ptr>> SharedCache::GetExpor return nullptr; } - auto exportList = SharedCache::ParseExportTrie(linkeditFile, header); + // FIXME: This is the only place ParseExportTrie is used, it can be optimized for the output we need here. + std::vector> exportList = SharedCache::ParseExportTrie(linkeditFile, header); auto exportMapping = std::make_shared>>(exportList.size()); - for (const auto& sym : exportList) + for (auto& sym : exportList) { - exportMapping->insert_or_assign(sym->GetAddress(), sym); + exportMapping->insert_or_assign(sym->GetAddress(), std::move(sym)); } MutableState().exportInfos.emplace(header.textBase, exportMapping); if (didModifyExportList) @@ -2847,6 +2816,7 @@ std::shared_ptr>> SharedCache::GetExpor std::vector SharedCache::GetAvailableImages() { std::vector installNames; + installNames.reserve(State().headers.size()); for (const auto& header : State().headers) { installNames.push_back(header.second.installName); @@ -2862,26 +2832,51 @@ std::vector>> SharedCache::LoadAllSymbolsAndW std::lock_guard initialLoadBlock(m_viewSpecificState->viewOperationsThatInfluenceMetadataMutex); bool doSave = false; - std::vector>> symbols; + std::vector>>> exportLists; + exportLists.reserve(State().images.size()); + + size_t totalSymbolCount = 0; + for (const auto& img : State().images) { auto header = HeaderForAddress(img.headerLocation); auto exportList = GetExportListForHeader(*header, [&]() { - try { - auto mapping = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), header->exportTriePath)->lock(); - return mapping; - } - catch (...) - { - m_logger->LogWarn("Serious Error: Failed to open export trie %s for %s", header->exportTriePath.c_str(), header->installName.c_str()); - return std::shared_ptr(nullptr); - } - }, &doSave); - if (!exportList) + try { + auto mapping = MMappedFileAccessor::Open( + m_dscView, + m_dscView->GetFile()->GetSessionId(), + header->exportTriePath + )->lock(); + return mapping; + } + catch (...) + { + m_logger->LogWarn("Serious Error: Failed to open export trie %s for %s", + header->exportTriePath.c_str(), + header->installName.c_str()); + return std::shared_ptr(nullptr); + } + }, &doSave); + + exportLists.push_back(exportList); + if (exportList) + { + totalSymbolCount += exportList->size(); + } + } + + std::vector>> symbols; + symbols.reserve(totalSymbolCount); + + for (size_t i = 0; i < exportLists.size(); ++i) + { + if (!exportLists[i]) continue; - for (const auto& [_, symbol] : *exportList) + + const auto& img = State().images[i]; + for (const auto& [name, symbol] : *exportLists[i]) { - symbols.push_back({img.installName, symbol}); + symbols.emplace_back(img.installName, symbol); } } @@ -3144,6 +3139,7 @@ extern "C" *count = value.size(); std::vector cstrings; + cstrings.reserve(value.size()); for (size_t i = 0; i < value.size(); i++) { cstrings.push_back(value[i].c_str()); @@ -3567,7 +3563,9 @@ void SharedCache::Load(DeserializationContext& context) { std::vector>> symbolInfos; - for (auto& si : symbolInfo["value"].GetArray()) + auto symbolInfoArray = symbolInfo["value"].GetArray(); + symbolInfos.reserve(symbolInfoArray.Size()); + for (auto& si : symbolInfoArray) { symbolInfos.push_back({si["key"].GetUint64(), {static_cast(si["val1"].GetUint64()), si["val2"].GetString()}}); -- cgit v1.3.1