From c8b6ae27e7c4f379278831b5b5cfc57863233f00 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Mon, 13 Jan 2025 23:36:24 -0800 Subject: [SharedCache] Optimize parsing of slide info Slide info is parsed and applied on the main thread, below the `SharedCache` constructor, when a shared cache is opened. Time spent applying the slide is time that the main thread is blocked. These changes eliminate some unnecessary overhead so what work remains is dominated by kernel work (paging in data, copying pages when the first modification is made). The changes are: 1. Read slide pointers via `ReadULong` rather than the variable-length `Read` method. The compiler isn't able to eliminate the call to `memcpy` in the variable-length `Read` function, and the function call overhead is noticeable given the small size of the read and number of times it is called. 2. Remove the file member from `MappingInfo`. Slide info is applied for a single file at a time so there's no reason to track the file it belongs to. This removes unnecesssary reference counting on the `std::shared_ptr` that holds the `MMappedFileAccessor`. --- view/sharedcache/core/SharedCache.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'view/sharedcache/core/SharedCache.cpp') diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index a696e9b3..f4580d3d 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -1157,7 +1157,6 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrRead(&map.mappingInfo, baseHeader.mappingOffset + sizeof(dyld_cache_mapping_info), sizeof(dyld_cache_mapping_info)); - map.file = file; map.slideInfoVersion = slideInfoVersion; if (map.slideInfoVersion == 2) file->Read(&map.slideInfoV2, slideInfoOff, sizeof(dyld_cache_slide_info_v2)); @@ -1183,7 +1182,6 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrReadUInt32(mappingAndSlideInfo.slideInfoFileOffset); @@ -1251,7 +1249,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrReadUShort(cursor); + uint16_t start = file->ReadUShort(cursor); cursor += sizeof(uint16_t); if (start == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE) continue; @@ -1301,7 +1299,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrReadUShort(extraCursor); + auto extra = file->ReadUShort(extraCursor); uint16_t aStart = extra; uint64_t page = mapping.mappingInfo.fileOffset + (pageSize * i); uint16_t pageStartOffset = (aStart & 0x3FFF)*4; @@ -1340,7 +1338,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrReadUShort(cursor); + uint16_t delta = file->ReadUShort(cursor); cursor += sizeof(uint16_t); if (delta == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE) continue; @@ -1352,8 +1350,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrRead(&slideInfo, loc, sizeof(slideInfo)); + dyld_cache_slide_pointer3 slideInfo = { file->ReadULong(loc) }; delta = slideInfo.plain.offsetToNextPointer; if (slideInfo.auth.authenticated) @@ -1395,7 +1392,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrReadUShort(cursor); + uint16_t delta = file->ReadUShort(cursor); cursor += sizeof(uint16_t); if (delta == DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE) continue; @@ -1407,8 +1404,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrRead(&slideInfo, loc, sizeof(slideInfo)); + dyld_cache_slide_pointer5 slideInfo = { file->ReadULong(loc) }; delta = slideInfo.regular.next; if (slideInfo.auth.auth) { -- cgit v1.3.1