@@ -290,27 +290,26 @@ typedef struct {
290
290
const char *start;
291
291
size_t size;
292
292
} DeferredFile;
293
+ typedef std::vector<DeferredFile> DeferredFiles;
294
+
295
+ typedef struct {
296
+ DeferredFiles deferred;
297
+ size_t counter, total, pageSize;
298
+ pthread_mutex_t mutex;
299
+ } PageInState;
293
300
294
301
// Most input files have been mapped but not yet paged in.
295
302
// This code forces the page-ins on multiple threads so
296
303
// the process is not stalled waiting on disk buffer i/o.
297
- static void multiThreadedPageIn (std::vector<DeferredFile> &deferred ) {
304
+ static void multiThreadedPageInBackground (PageInState *state ) {
298
305
#ifndef _WIN32
299
306
#define MaxReadThreads 200
300
- typedef struct {
301
- std::vector<DeferredFile> &deferred;
302
- size_t counter, total, pageSize;
303
- pthread_mutex_t mutex;
304
- } PageInState;
305
- PageInState state = {deferred, 0 , 0 ,
306
- llvm::sys::Process::getPageSizeEstimate (),
307
- pthread_mutex_t ()};
308
307
static size_t totalBytes;
309
308
310
309
pthread_t running[MaxReadThreads];
311
310
if (config->readThreads > MaxReadThreads)
312
311
config->readThreads = MaxReadThreads;
313
- pthread_mutex_init (&state. mutex , NULL );
312
+ pthread_mutex_init (&state-> mutex , nullptr );
314
313
315
314
for (int t = 0 ; t < config->readThreads ; t++)
316
315
pthread_create (
@@ -336,18 +335,46 @@ static void multiThreadedPageIn(std::vector<DeferredFile> &deferred) {
336
335
state.total += t; // Avoids the loop being optimised out.
337
336
}
338
337
},
339
- & state);
338
+ state);
340
339
341
340
for (int t = 0 ; t < config->readThreads ; t++)
342
341
pthread_join (running[t], nullptr );
343
342
344
- pthread_mutex_destroy (&state. mutex );
343
+ pthread_mutex_destroy (&state-> mutex );
345
344
if (getenv (" LLD_MULTI_THREAD_PAGE" ))
346
- printf (" multiThreadedPageIn %ld/%ld\n " , totalBytes, deferred.size ());
345
+ printf (" multiThreadedPageIn %ld/%ld\n " , totalBytes, state-> deferred .size ());
347
346
#endif
348
347
}
349
348
349
+ static void multiThreadedPageIn (DeferredFiles deferred) {
350
+ static pthread_t running;
351
+ static pthread_mutex_t busy;
352
+
353
+ if (running)
354
+ pthread_join (running, nullptr );
355
+ else
356
+ pthread_mutex_init (&busy, nullptr );
357
+
358
+ pthread_mutex_lock (&busy);
359
+ PageInState *state = new PageInState {
360
+ deferred, 0 , 0 ,
361
+ llvm::sys::Process::getPageSizeEstimate (),
362
+ pthread_mutex_t ()};
363
+
364
+ pthread_create (
365
+ &running, nullptr ,
366
+ [](void *ptr) -> void * {
367
+ PageInState *state = (PageInState *)ptr;
368
+ multiThreadedPageInBackground (state);
369
+ pthread_mutex_unlock (&busy);
370
+ delete state;
371
+ return nullptr ;
372
+ },
373
+ state);
374
+ }
375
+
350
376
static InputFile *processFile (std::optional<MemoryBufferRef> buffer,
377
+ DeferredFiles *archiveContents,
351
378
StringRef path, LoadType loadType,
352
379
bool isLazy = false , bool isExplicit = true ,
353
380
bool isBundleLoader = false ,
@@ -431,7 +458,6 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
431
458
// we already found that it contains an ObjC symbol.
432
459
if (readFile (path)) {
433
460
Error e = Error::success ();
434
- std::vector<DeferredFile> deferredFiles;
435
461
for (const object::Archive::Child &c : file->getArchive ().children (e)) {
436
462
Expected<MemoryBufferRef> mb = c.getMemoryBufferRef ();
437
463
if (!mb) {
@@ -445,9 +471,10 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
445
471
continue ;
446
472
}
447
473
448
- deferredFiles.push_back ({path, isLazy, std::nullopt,
449
- mb->getBuffer ().data (),
450
- mb->getBuffer ().size ()});
474
+ if (archiveContents)
475
+ archiveContents->push_back ({path, isLazy, std::nullopt,
476
+ mb->getBuffer ().data (),
477
+ mb->getBuffer ().size ()});
451
478
if (!hasObjCSection (*mb))
452
479
continue ;
453
480
if (Error e = file->fetch (c, " -ObjC" ))
@@ -457,11 +484,14 @@ static InputFile *processFile(std::optional<MemoryBufferRef> buffer,
457
484
if (e)
458
485
error (toString (file) +
459
486
" : Archive::children failed: " + toString (std::move (e)));
460
- if (config->readThreads && deferredFiles.size () > 1 )
461
- multiThreadedPageIn (deferredFiles);
487
+ // if (archiveContents && !archiveContents->empty()) {
488
+ // multiThreadedPageIn(*archiveContents);
489
+ // archiveContents->clear();
490
+ // }
462
491
}
463
492
}
464
- file->addLazySymbols ();
493
+ if (!archiveContents || archiveContents->empty ())
494
+ file->addLazySymbols ();
465
495
loadedArchives[path] = ArchiveFileInfo{file, isCommandLineLoad};
466
496
newFile = file;
467
497
break ;
@@ -516,18 +546,17 @@ static InputFile *addFile(StringRef path, LoadType loadType,
516
546
bool isLazy = false , bool isExplicit = true ,
517
547
bool isBundleLoader = false ,
518
548
bool isForceHidden = false ) {
519
- return processFile (readFile (path), path, loadType, isLazy, isExplicit ,
520
- isBundleLoader, isForceHidden);
549
+ return processFile (readFile (path), nullptr , path, loadType, isLazy,
550
+ isExplicit, isBundleLoader, isForceHidden);
521
551
}
522
552
523
- static void deferFile (StringRef path, bool isLazy,
524
- std::vector<DeferredFile> &deferred) {
553
+ static void deferFile (StringRef path, bool isLazy, DeferredFiles &deferred) {
525
554
std::optional<MemoryBufferRef> buffer = readFile (path);
526
555
if (config->readThreads )
527
556
deferred.push_back ({path, isLazy, buffer, buffer->getBuffer ().data (),
528
557
buffer->getBuffer ().size ()});
529
558
else
530
- processFile (buffer, path, LoadType::CommandLine, isLazy);
559
+ processFile (buffer, nullptr , path, LoadType::CommandLine, isLazy);
531
560
}
532
561
533
562
static std::vector<StringRef> missingAutolinkWarnings;
@@ -654,7 +683,7 @@ void macho::resolveLCLinkerOptions() {
654
683
}
655
684
656
685
static void addFileList (StringRef path, bool isLazy,
657
- std::vector<DeferredFile> &deferredFiles) {
686
+ DeferredFiles &deferredFiles) {
658
687
std::optional<MemoryBufferRef> buffer = readFile (path);
659
688
if (!buffer)
660
689
return ;
@@ -1312,7 +1341,7 @@ static void createFiles(const InputArgList &args) {
1312
1341
bool isLazy = false ;
1313
1342
// If we've processed an opening --start-lib, without a matching --end-lib
1314
1343
bool inLib = false ;
1315
- std::vector<DeferredFile> deferredFiles;
1344
+ DeferredFiles deferredFiles;
1316
1345
1317
1346
for (const Arg *arg : args) {
1318
1347
const Option &opt = arg->getOption ();
@@ -1390,8 +1419,20 @@ static void createFiles(const InputArgList &args) {
1390
1419
1391
1420
if (config->readThreads ) {
1392
1421
multiThreadedPageIn (deferredFiles);
1422
+
1423
+ DeferredFiles archiveContents;
1424
+ std::vector<ArchiveFile *> archives;
1393
1425
for (auto &file : deferredFiles)
1394
- processFile (file.buffer , file.path , LoadType::CommandLine, file.isLazy );
1426
+ if (ArchiveFile *archive = dyn_cast<ArchiveFile>
1427
+ (processFile (file.buffer , &archiveContents, file.path ,
1428
+ LoadType::CommandLine, file.isLazy )))
1429
+ archives.push_back (archive);
1430
+
1431
+ if (!archiveContents.empty ()) {
1432
+ multiThreadedPageIn (archiveContents);
1433
+ for (auto *archive : archives)
1434
+ archive->addLazySymbols ();
1435
+ }
1395
1436
}
1396
1437
}
1397
1438
0 commit comments