summaryrefslogtreecommitdiff
path: root/tools/llvm-ar
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-01-22 16:43:45 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-01-22 16:43:45 +0000
commitfa4a8f4f5a6de6e205f4685196d3d535a395c152 (patch)
treec5f21fdbd34bb56a8f1ec944495c9a827ba3ed99 /tools/llvm-ar
parent7dd91217c74d02bc6fee3747b77a6c9c67b5530b (diff)
downloadllvm-fa4a8f4f5a6de6e205f4685196d3d535a395c152.tar.gz
llvm-fa4a8f4f5a6de6e205f4685196d3d535a395c152.tar.bz2
llvm-fa4a8f4f5a6de6e205f4685196d3d535a395c152.tar.xz
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
Diffstat (limited to 'tools/llvm-ar')
-rw-r--r--tools/llvm-ar/llvm-ar.cpp62
1 files changed, 46 insertions, 16 deletions
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index d4fe7d789c..b2081e1a7b 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -395,17 +395,25 @@ namespace {
class NewArchiveIterator {
bool IsNewMember;
StringRef Name;
+
object::Archive::child_iterator OldI;
+
std::string NewFilename;
+ mutable int NewFD;
+ mutable sys::fs::file_status NewStatus;
public:
NewArchiveIterator(object::Archive::child_iterator I, StringRef Name);
NewArchiveIterator(std::string *I, StringRef Name);
NewArchiveIterator();
bool isNewMember() const;
+ StringRef getName() const;
+
object::Archive::child_iterator getOld() const;
+
const char *getNew() const;
- StringRef getName() const;
+ int getFD() const;
+ const sys::fs::file_status &getStatus() const;
};
}
@@ -416,7 +424,7 @@ NewArchiveIterator::NewArchiveIterator(object::Archive::child_iterator I,
: IsNewMember(false), Name(Name), OldI(I) {}
NewArchiveIterator::NewArchiveIterator(std::string *NewFilename, StringRef Name)
- : IsNewMember(true), Name(Name), NewFilename(*NewFilename) {}
+ : IsNewMember(true), Name(Name), NewFilename(*NewFilename), NewFD(-1) {}
StringRef NewArchiveIterator::getName() const { return Name; }
@@ -432,6 +440,31 @@ const char *NewArchiveIterator::getNew() const {
return NewFilename.c_str();
}
+int NewArchiveIterator::getFD() const {
+ assert(IsNewMember);
+ if (NewFD != -1)
+ return NewFD;
+ failIfError(sys::fs::openFileForRead(NewFilename, NewFD), NewFilename);
+ assert(NewFD != -1);
+
+ failIfError(sys::fs::status(NewFD, NewStatus), NewFilename);
+
+ // Opening a directory doesn't make sense. Let it fail.
+ // Linux cannot open directories with open(2), although
+ // cygwin and *bsd can.
+ if (NewStatus.type() == sys::fs::file_type::directory_file)
+ failIfError(error_code(errc::is_a_directory, posix_category()),
+ NewFilename);
+
+ return NewFD;
+}
+
+const sys::fs::file_status &NewArchiveIterator::getStatus() const {
+ assert(IsNewMember);
+ assert(NewFD != -1 && "Must call getFD first");
+ return NewStatus;
+}
+
template <typename T>
void addMember(std::vector<NewArchiveIterator> &Members, T I, StringRef Name,
int Pos = -1) {
@@ -670,8 +703,16 @@ static void writeSymbolTable(
object::ObjectFile *Obj;
if (I->isNewMember()) {
const char *Filename = I->getNew();
+ int FD = I->getFD();
+ const sys::fs::file_status &Status = I->getStatus();
+
+ OwningPtr<MemoryBuffer> File;
+ failIfError(MemoryBuffer::getOpenFile(FD, Filename, File,
+ Status.getSize(), false),
+ Filename);
+
if (ErrorOr<object::ObjectFile *> ObjOrErr =
- object::ObjectFile::createObjectFile(Filename))
+ object::ObjectFile::createObjectFile(File.take()))
Obj = ObjOrErr.get();
else
Obj = NULL;
@@ -786,19 +827,8 @@ static void performWriteOperation(ArchiveOperation Operation,
if (I->isNewMember()) {
const char *FileName = I->getNew();
-
- int FD;
- failIfError(sys::fs::openFileForRead(FileName, FD), FileName);
-
- sys::fs::file_status Status;
- failIfError(sys::fs::status(FD, Status), FileName);
-
- // Opening a directory doesn't make sense. Let it failed.
- // Linux cannot open directories with open(2), although
- // cygwin and *bsd can.
- if (Status.type() == sys::fs::file_type::directory_file)
- failIfError(error_code(errc::is_a_directory, posix_category()),
- FileName);
+ int FD = I->getFD();
+ const sys::fs::file_status &Status = I->getStatus();
OwningPtr<MemoryBuffer> File;
failIfError(MemoryBuffer::getOpenFile(FD, FileName, File,