llvm.org GIT mirror llvm / fa4a8f4
Don't open or fstat files twice in llvm-ar. We still read/mmap them twice, but the fix for that is a bit more complex. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199815 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
1 changed file(s) with 46 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
394394 class NewArchiveIterator {
395395 bool IsNewMember;
396396 StringRef Name;
397
397398 object::Archive::child_iterator OldI;
399
398400 std::string NewFilename;
401 mutable int NewFD;
402 mutable sys::fs::file_status NewStatus;
399403
400404 public:
401405 NewArchiveIterator(object::Archive::child_iterator I, StringRef Name);
402406 NewArchiveIterator(std::string *I, StringRef Name);
403407 NewArchiveIterator();
404408 bool isNewMember() const;
409 StringRef getName() const;
410
405411 object::Archive::child_iterator getOld() const;
412
406413 const char *getNew() const;
407 StringRef getName() const;
414 int getFD() const;
415 const sys::fs::file_status &getStatus() const;
408416 };
409417 }
410418
415423 : IsNewMember(false), Name(Name), OldI(I) {}
416424
417425 NewArchiveIterator::NewArchiveIterator(std::string *NewFilename, StringRef Name)
418 : IsNewMember(true), Name(Name), NewFilename(*NewFilename) {}
426 : IsNewMember(true), Name(Name), NewFilename(*NewFilename), NewFD(-1) {}
419427
420428 StringRef NewArchiveIterator::getName() const { return Name; }
421429
429437 const char *NewArchiveIterator::getNew() const {
430438 assert(IsNewMember);
431439 return NewFilename.c_str();
440 }
441
442 int NewArchiveIterator::getFD() const {
443 assert(IsNewMember);
444 if (NewFD != -1)
445 return NewFD;
446 failIfError(sys::fs::openFileForRead(NewFilename, NewFD), NewFilename);
447 assert(NewFD != -1);
448
449 failIfError(sys::fs::status(NewFD, NewStatus), NewFilename);
450
451 // Opening a directory doesn't make sense. Let it fail.
452 // Linux cannot open directories with open(2), although
453 // cygwin and *bsd can.
454 if (NewStatus.type() == sys::fs::file_type::directory_file)
455 failIfError(error_code(errc::is_a_directory, posix_category()),
456 NewFilename);
457
458 return NewFD;
459 }
460
461 const sys::fs::file_status &NewArchiveIterator::getStatus() const {
462 assert(IsNewMember);
463 assert(NewFD != -1 && "Must call getFD first");
464 return NewStatus;
432465 }
433466
434467 template
669702 object::ObjectFile *Obj;
670703 if (I->isNewMember()) {
671704 const char *Filename = I->getNew();
705 int FD = I->getFD();
706 const sys::fs::file_status &Status = I->getStatus();
707
708 OwningPtr File;
709 failIfError(MemoryBuffer::getOpenFile(FD, Filename, File,
710 Status.getSize(), false),
711 Filename);
712
672713 if (ErrorOr ObjOrErr =
673 object::ObjectFile::createObjectFile(Filename))
714 object::ObjectFile::createObjectFile(File.take()))
674715 Obj = ObjOrErr.get();
675716 else
676717 Obj = NULL;
785826
786827 if (I->isNewMember()) {
787828 const char *FileName = I->getNew();
788
789 int FD;
790 failIfError(sys::fs::openFileForRead(FileName, FD), FileName);
791
792 sys::fs::file_status Status;
793 failIfError(sys::fs::status(FD, Status), FileName);
794
795 // Opening a directory doesn't make sense. Let it failed.
796 // Linux cannot open directories with open(2), although
797 // cygwin and *bsd can.
798 if (Status.type() == sys::fs::file_type::directory_file)
799 failIfError(error_code(errc::is_a_directory, posix_category()),
800 FileName);
829 int FD = I->getFD();
830 const sys::fs::file_status &Status = I->getStatus();
801831
802832 OwningPtr File;
803833 failIfError(MemoryBuffer::getOpenFile(FD, FileName, File,