Loading...
cache_builder/NewSharedCacheBuilder.cpp dyld-1125.5 dyld-1122.1
--- dyld/dyld-1125.5/cache_builder/NewSharedCacheBuilder.cpp
+++ dyld/dyld-1122.1/cache_builder/NewSharedCacheBuilder.cpp
@@ -112,7 +112,7 @@
 }
 
 void SharedCacheBuilder::addFile(const void* buffer, size_t bufferSize, std::string_view path,
-                                 uint64_t inode, uint64_t modTime, bool forceNotCacheEligible)
+                                 uint64_t inode, uint64_t modTime)
 {
     Diagnostics diag;
     const bool  isOSBinary = false;
@@ -120,11 +120,10 @@
                                                           this->options.platform, isOSBinary,
                                                           this->options.archs) ) {
         InputFile inputFile;
-        inputFile.mf                    = mf;
-        inputFile.inode                 = inode;
-        inputFile.mtime                 = modTime;
-        inputFile.path                  = path;
-        inputFile.forceNotCacheEligible = forceNotCacheEligible;
+        inputFile.mf        = mf;
+        inputFile.inode     = inode;
+        inputFile.mtime     = modTime;
+        inputFile.path      = path;
         allInputFiles.push_back(std::move(inputFile));
         return;
     }
@@ -136,11 +135,10 @@
                                                               dyld3::Platform::iOSMac, isOSBinary,
                                                               this->options.archs) ) {
             InputFile inputFile;
-            inputFile.mf                    = mf;
-            inputFile.inode                 = inode;
-            inputFile.mtime                 = modTime;
-            inputFile.path                  = path;
-            inputFile.forceNotCacheEligible = forceNotCacheEligible;
+            inputFile.mf        = mf;
+            inputFile.inode     = inode;
+            inputFile.mtime     = modTime;
+            inputFile.path      = path;
             allInputFiles.push_back(std::move(inputFile));
             return;
         }
@@ -519,7 +517,7 @@
                 }
             }
 
-            if ( !inputFile.forceNotCacheEligible && inputFile.mf->canBePlacedInDyldCache(dylibPath.data(), failureHandler) ) {
+            if ( inputFile.mf->canBePlacedInDyldCache(dylibPath.data(), failureHandler) ) {
                 CacheDylib cacheDylib(inputFile);
                 this->cacheDylibs.push_back(std::move(cacheDylib));
             }
@@ -980,27 +978,6 @@
             // diag.warning("libobjc's magical IMP caches shared cache offsets list section missing (metadata not optimized)");
             return;
         }
-
-        // Also find the _objc_opt_preopt_caches_version symbol, which has the IMP caches version
-        __block Diagnostics diag;
-        cacheDylib.inputMF->withFileLayout(diag, ^(const mach_o::Layout &layout) {
-            mach_o::Layout::FoundSymbol foundInfo;
-            if ( !layout.findExportedSymbol(diag, "_objc_opt_preopt_caches_version", false, foundInfo) )
-                return;
-
-            // We only support header offsets in this dylib, as we are looking for self binds
-            // which are likely only to classes
-            if ( foundInfo.kind != mach_o::Layout::FoundSymbol::Kind::headerOffset )
-                return;
-
-            uint64_t vmAddr = layout.textUnslidVMAddr() + foundInfo.value;
-
-            __block objc_visitor::Visitor objcVisitor = makeInputDylibObjCVisitor(cacheDylib);
-            metadata_visitor::ResolvedValue value = objcVisitor.getValueFor(VMAddress(vmAddr));
-            this->objcIMPCachesOptimizer.libobjcImpCachesVersion = *(int*)value.value();
-        });
-        if ( diag.hasError() )
-            return;
     }
 
     // Find all the objc dylibs, classes, categories
@@ -4130,6 +4107,12 @@
         assert(this->totalVMSize == totalCustomerCacheSize);
     }
 
+    if ( this->totalVMSize > this->config.layout.cacheSize ) {
+        return Error("Cache overflow (0x%llx > 0x%llx)",
+                     this->totalVMSize.rawValue(),
+                     this->config.layout.cacheSize.rawValue());
+    }
+
     return Error();
 }
 
@@ -4157,7 +4140,6 @@
 
                 // Check for overflow
                 if ( region.subCacheVMSize > this->config.layout.discontiguous->simTextSize ) {
-                    evictLeafDylibs(region.subCacheVMSize - this->config.layout.discontiguous->simTextSize);
                     return Error("Overflow in text (0x%llx > 0x%llx)",
                                  region.subCacheVMSize.rawValue(),
                                  this->config.layout.discontiguous->simTextSize.rawValue());
@@ -4314,105 +4296,14 @@
     }
 
     this->totalVMSize = CacheVMSize((vmAddress - this->config.layout.cacheBaseAddress).rawValue());
+    
+    if ( this->totalVMSize > this->config.layout.cacheSize ) {
+        return Error("Cache overflow (0x%llx > 0x%llx)",
+                     this->totalVMSize.rawValue(),
+                     this->config.layout.cacheSize.rawValue());
+    }
 
     return Error();
-}
-
-void SharedCacheBuilder::evictLeafDylibs(CacheVMSize reductionTarget)
-{
-    // build a reverse map of all dylib dependencies
-    std::unordered_map<std::string_view, std::unordered_set<std::string_view>> references;
-    // Ensure we have an entry (even if it is empty)
-    for ( const CacheDylib& cacheDylib : cacheDylibs )
-        references[cacheDylib.installName] = { };
-    
-    for ( const CacheDylib& cacheDylib : cacheDylibs ) {
-        for ( const CacheDylib::DependentDylib& depDylib : cacheDylib.dependents ) {
-            // Skip missing weak links
-            if ( depDylib.dylib == nullptr )
-                continue;
-            references[depDylib.dylib->installName].insert(cacheDylib.installName);
-        }
-    }
-
-    struct DylibAndSize
-    {
-        CacheDylib* dylib;
-        CacheVMSize size;
-    };
-
-    // Find the sizes of all the dylibs
-    std::vector<DylibAndSize> dylibsToSort;
-    for ( CacheDylib& cacheDylib : cacheDylibs ) {
-        CacheVMSize segsSize = CacheVMSize(0ULL);
-        for ( const DylibSegmentChunk& segment : cacheDylib.segments ) {
-            if ( segment.segmentName == "__LINKEDIT" )
-                continue;
-
-            segsSize += segment.cacheVMSize;
-        }
-        dylibsToSort.push_back({ &cacheDylib, segsSize });
-    }
-
-    // Build an ordered list of what to remove. At each step we do following
-    // 1) Find all dylibs that nothing else depends on
-    // 2a) If any of those dylibs are not in the order select the largest one of them
-    // 2b) If all the leaf dylibs are in the order file select the last dylib that appears last in the order file
-    // 3) Remove all entries to the removed file from the reverse dependency map
-    // 4) Go back to one and repeat until there are no more evictable dylibs
-    // This results in us always choosing the locally optimal selection, and then taking into account how that impacts
-    // the dependency graph for subsequent selections
-
-    std::vector<DylibAndSize> sortedDylibs;
-    bool candidateFound = true;
-    while ( candidateFound ) {
-        candidateFound = false;
-        DylibAndSize candidate;
-        uint64_t candidateOrder = 0;
-        for( const auto& dylib : dylibsToSort ) {
-            const auto& dylibRefs = references.at(dylib.dylib->installName);
-            if ( !dylibRefs.empty())
-                continue;
-
-            const auto& j = options.dylibOrdering.find(std::string(dylib.dylib->installName));
-            uint64_t order = 0;
-            if ( j != options.dylibOrdering.end() ) {
-                order = j->second;
-            } else {
-                // Not in the order file, set order sot it goes to the front of the list
-                order = UINT64_MAX;
-            }
-            if ( order > candidateOrder || (order == UINT64_MAX && candidate.size < dylib.size) ) {
-                // The new file is either a lower priority in the order file
-                // or the same priority as the candidate but larger
-                candidate = dylib;
-                candidateOrder = order;
-                candidateFound = true;
-            }
-        }
-        if (candidateFound) {
-            sortedDylibs.push_back(candidate);
-            references.erase(candidate.dylib->installName);
-            for (auto& dependent : references) {
-                (void)dependent.second.erase(candidate.dylib->installName);
-            }
-            auto j = std::find_if(dylibsToSort.begin(), dylibsToSort.end(),
-                                  [&candidate](const DylibAndSize& dylib) {
-                return candidate.dylib->installName == dylib.dylib->installName;
-            });
-            if ( j != dylibsToSort.end() ) {
-                dylibsToSort.erase(j);
-            }
-        }
-    }
-
-     // build set of dylibs that if removed will allow cache to build
-    for ( DylibAndSize& dylib : sortedDylibs ) {
-        this->evictedDylibs.push_back(dylib.dylib->inputFile->path);
-        if ( dylib.size > reductionTarget )
-            break;
-        reductionTarget -= dylib.size;
-    }
 }
 
 // In file layout, we need each Region to start page-aligned.  Within a Region, we can pack pages
@@ -4499,13 +4390,6 @@
                 return error;
         }
     }
-    
-    if ( this->totalVMSize > this->config.layout.cacheSize ) {
-        evictLeafDylibs(this->totalVMSize - this->config.layout.cacheSize);
-        return Error("Cache overflow (0x%llx > 0x%llx)",
-                     this->totalVMSize.rawValue(),
-                     this->config.layout.cacheSize.rawValue());
-    }
 
     // Update Section VMAddr's now that we know where all the Region's are in memory
     for ( SubCache& subCache : this->subCaches ) {
@@ -4519,6 +4403,12 @@
                 }
             }
         }
+    }
+
+    if ( this->totalVMSize > this->config.layout.cacheSize ) {
+        return Error("Cache overflow (0x%llx > 0x%llx)",
+                     this->totalVMSize.rawValue(),
+                     this->config.layout.cacheSize.rawValue());
     }
 
     return Error();
@@ -6552,7 +6442,7 @@
 
     Timer::Scope timedScope(this->config, "emitCanonicalObjCProtocols time");
 
-    const bool log = false;
+    const bool log = this->options.debug;
 
     // We need to find the Protocol class from libojc
     VMAddress                  protocolClassVMAddr;
@@ -6728,7 +6618,7 @@
 
     Timer::Scope timedScope(this->config, "computeObjCClassLayout time");
 
-    const bool log = false;
+    const bool log = this->options.debug;
 
     // We need to walk all classes in all dylibs.  Each dylib needs its own objc visitor object
     std::vector<objc_visitor::Visitor> objcVisitors;
@@ -7594,11 +7484,6 @@
     return buff;
 }
 
-std::span<const std::string_view> SharedCacheBuilder::getEvictedDylibs() const
-{
-    return this->evictedDylibs;
-}
-
 void SharedCacheBuilder::getResults(std::vector<CacheBuffer>& results) const
 {
     for ( const SubCache& subCache : this->subCaches ) {