@@ -283,11 +283,11 @@ static void saveThinArchiveToRepro(ArchiveFile const *file) {
283283 " : Archive::children failed: " + toString (std::move (e)));
284284}
285285
286- static InputFile *deferredAddFile (std::optional<MemoryBufferRef> buffer,
287- StringRef path, LoadType loadType,
288- bool isLazy = false , bool isExplicit = true ,
289- bool isBundleLoader = false ,
290- bool isForceHidden = false ) {
286+ static InputFile *processFile (std::optional<MemoryBufferRef> buffer,
287+ StringRef path, LoadType loadType,
288+ bool isLazy = false , bool isExplicit = true ,
289+ bool isBundleLoader = false ,
290+ bool isForceHidden = false ) {
291291 if (!buffer)
292292 return nullptr ;
293293 MemoryBufferRef mbref = *buffer;
@@ -446,8 +446,24 @@ static InputFile *addFile(StringRef path, LoadType loadType,
446446 bool isLazy = false , bool isExplicit = true ,
447447 bool isBundleLoader = false ,
448448 bool isForceHidden = false ) {
449- return deferredAddFile (readFile (path), path, loadType, isLazy, isExplicit,
450- isBundleLoader, isForceHidden);
449+ return processFile (readFile (path), path, loadType, isLazy, isExplicit,
450+ isBundleLoader, isForceHidden);
451+ }
452+
453+ typedef struct {
454+ StringRef path;
455+ LoadType loadType;
456+ bool isLazy;
457+ std::optional<MemoryBufferRef> buffer;
458+ } DeferredFile;
459+
460+ static void deferFile (StringRef path, LoadType loadType, bool isLazy,
461+ std::vector<DeferredFile> &deferred) {
462+ std::optional<MemoryBufferRef> buffer = readFile (path);
463+ if (config->readThreads )
464+ deferred.push_back ({path, loadType, isLazy, buffer});
465+ else
466+ processFile (buffer, path, loadType, isLazy);
451467}
452468
453469static std::vector<StringRef> missingAutolinkWarnings;
@@ -573,23 +589,14 @@ void macho::resolveLCLinkerOptions() {
573589 }
574590}
575591
576- typedef struct {
577- StringRef path;
578- std::optional<MemoryBufferRef> buffer;
579- } DeferredFile;
580-
581592static void addFileList (StringRef path, bool isLazy,
582593 std::vector<DeferredFile> &deferredFiles) {
583594 std::optional<MemoryBufferRef> buffer = readFile (path);
584595 if (!buffer)
585596 return ;
586597 MemoryBufferRef mbref = *buffer;
587598 for (StringRef path : args::getLines (mbref))
588- if (config->readThreads ) {
589- StringRef rrpath = rerootPath (path);
590- deferredFiles.push_back ({rrpath, readFile (rrpath)});
591- } else
592- addFile (rerootPath (path), LoadType::CommandLine, isLazy);
599+ deferFile (rerootPath (path), LoadType::CommandLine, isLazy, deferredFiles);
593600}
594601
595602// We expect sub-library names of the form "libfoo", which will match a dylib
@@ -1239,43 +1246,44 @@ static void handleSymbolPatterns(InputArgList &args,
12391246// the process is not stalled waiting on disk buffer i/o.
12401247void multiThreadedPageIn (std::vector<DeferredFile> &deferred, int nthreads) {
12411248#ifndef _WIN32
1249+ #define MaxReadThreads 200
12421250 typedef struct {
12431251 std::vector<DeferredFile> &deferred;
1244- size_t counter, total, pageSize;
1252+ size_t counter, bytes, total, pageSize;
12451253 pthread_mutex_t mutex;
12461254 } PageInState;
1247- PageInState state = {deferred, 0 , 0 ,
1248- llvm::sys::Process::getPageSizeEstimate (),
1249- pthread_mutex_t ()};
1255+ PageInState state = {
1256+ deferred, 0 , 0 , 0 , llvm::sys::Process::getPageSizeEstimate (),
1257+ pthread_mutex_t ()};
12501258 pthread_mutex_init (&state.mutex , NULL );
12511259
1252- pthread_t running[200 ];
1253- int maxthreads = sizeof running / sizeof running[0 ];
1254- if (nthreads > maxthreads)
1255- nthreads = maxthreads;
1260+ pthread_t running[MaxReadThreads];
1261+ if (nthreads > MaxReadThreads)
1262+ nthreads = MaxReadThreads;
12561263
12571264 for (int t = 0 ; t < nthreads; t++)
12581265 pthread_create (
12591266 &running[t], nullptr ,
12601267 [](void *ptr) -> void * {
12611268 PageInState &state = *(PageInState *)ptr;
1262- static int total = 0 ;
12631269 while (true ) {
12641270 pthread_mutex_lock (&state.mutex );
12651271 if (state.counter >= state.deferred .size ()) {
12661272 pthread_mutex_unlock (&state.mutex );
12671273 return nullptr ;
12681274 }
1269- DeferredFile &add = state.deferred [state.counter ];
1275+ DeferredFile &file = state.deferred [state.counter ];
12701276 state.counter += 1 ;
12711277 pthread_mutex_unlock (&state.mutex );
12721278
1279+ const char *page = file.buffer ->getBuffer ().data (),
1280+ *end = page + file.buffer ->getBuffer ().size ();
1281+ state.bytes += end - page;
1282+
12731283 int t = 0 ; // Reference each page to load it into memory.
1274- for (const char *page = add.buffer ->getBuffer ().data (),
1275- *end = page + add.buffer ->getBuffer ().size ();
1276- page < end; page += state.pageSize )
1284+ for (; page < end; page += state.pageSize )
12771285 t += *page;
1278- state.total += t; // Avoids whole section being optimised out.
1286+ state.total += t; // Avoids the loop being optimised out.
12791287 }
12801288 },
12811289 &state);
@@ -1303,12 +1311,8 @@ void createFiles(const InputArgList &args) {
13031311
13041312 switch (opt.getID ()) {
13051313 case OPT_INPUT:
1306- if (config->readThreads ) {
1307- StringRef rrpath = rerootPath (arg->getValue ());
1308- deferredFiles.push_back ({rrpath, readFile (rrpath)});
1309- break ;
1310- }
1311- addFile (rerootPath (arg->getValue ()), LoadType::CommandLine, isLazy);
1314+ deferFile (rerootPath (arg->getValue ()), LoadType::CommandLine, isLazy,
1315+ deferredFiles);
13121316 break ;
13131317 case OPT_needed_library:
13141318 if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
@@ -1377,8 +1381,8 @@ void createFiles(const InputArgList &args) {
13771381
13781382 if (config->readThreads ) {
13791383 multiThreadedPageIn (deferredFiles, config->readThreads );
1380- for (auto &add : deferredFiles)
1381- deferredAddFile (add .buffer , add .path , LoadType::CommandLine, isLazy);
1384+ for (auto &file : deferredFiles)
1385+ processFile (file .buffer , file .path , file. loadType , file. isLazy );
13821386 }
13831387}
13841388
0 commit comments