[lld] r238690 - COFF: Make the Driver own all MemoryBuffers. NFC.

Rui Ueyama ruiu at google.com
Sun May 31 14:04:56 PDT 2015


Author: ruiu
Date: Sun May 31 16:04:56 2015
New Revision: 238690

URL: http://llvm.org/viewvc/llvm-project?rev=238690&view=rev
Log:
COFF: Make the Driver own all MemoryBuffers. NFC.

Previously, a MemoryBuffer of a file was owned by each InputFile object.
This patch makes the Driver own all of them. InputFiles now have only
MemoryBufferRefs. This change simplifies ownership managment
(particularly for ObjectFile -- the object owned a MemoryBuffer only when
it's not created from an archive file, because in that case a parent
archive file owned the entire buffer. Now it owns nothing unconditionally.)

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/InputFiles.cpp
    lld/trunk/COFF/InputFiles.h
    lld/trunk/COFF/Symbols.cpp

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238690&r1=238689&r2=238690&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun May 31 16:04:56 2015
@@ -60,10 +60,18 @@ static std::string getOutputPath(llvm::o
   llvm_unreachable("internal error");
 }
 
-std::unique_ptr<InputFile> createFile(StringRef Path) {
+// Opens a file. Path has to be resolved already.
+// Newly created memory buffers are owned by this driver.
+ErrorOr<std::unique_ptr<InputFile>> LinkerDriver::createFile(StringRef Path) {
+  auto MBOrErr = MemoryBuffer::getFile(Path);
+  if (auto EC = MBOrErr.getError())
+    return EC;
+  std::unique_ptr<MemoryBuffer> MB = std::move(MBOrErr.get());
+  MemoryBufferRef MBRef = MB->getMemBufferRef();
+  OwningMBs.push_back(std::move(MB)); // take ownership
   if (StringRef(Path).endswith_lower(".lib"))
-    return llvm::make_unique<ArchiveFile>(Path);
-  return llvm::make_unique<ObjectFile>(Path);
+    return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
+  return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
 }
 
 namespace {
@@ -95,9 +103,15 @@ LinkerDriver::parseDirectives(StringRef
     return EC;
   std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
 
-  for (auto *Arg : Args->filtered(OPT_defaultlib))
-    if (Optional<StringRef> Path = findLib(Arg->getValue()))
-      Res->push_back(llvm::make_unique<ArchiveFile>(*Path));
+  for (auto *Arg : Args->filtered(OPT_defaultlib)) {
+    if (Optional<StringRef> Path = findLib(Arg->getValue())) {
+      auto FileOrErr = createFile(*Path);
+      if (auto EC = FileOrErr.getError())
+        return EC;
+      std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
+      Res->push_back(std::move(File));
+    }
+  }
   return std::error_code();
 }
 
@@ -289,7 +303,13 @@ bool LinkerDriver::link(int Argc, const
   // Parse all input files and put all symbols to the symbol table.
   // The symbol table will take care of name resolution.
   for (StringRef Path : Inputs) {
-    if (auto EC = Symtab.addFile(createFile(Path))) {
+    auto FileOrErr = createFile(Path);
+    if (auto EC = FileOrErr.getError()) {
+      llvm::errs() << Path << ": " << EC.message() << "\n";
+      return false;
+    }
+    std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
+    if (auto EC = Symtab.addFile(std::move(File))) {
       llvm::errs() << Path << ": " << EC.message() << "\n";
       return false;
     }

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=238690&r1=238689&r2=238690&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Sun May 31 16:04:56 2015
@@ -47,6 +47,9 @@ public:
 private:
   StringAllocator Alloc;
 
+  // Opens a file. Path has to be resolved already.
+  ErrorOr<std::unique_ptr<InputFile>> createFile(StringRef Path);
+
   // Searches a file from search paths.
   Optional<StringRef> findFile(StringRef Filename);
   Optional<StringRef> findLib(StringRef Filename);
@@ -59,6 +62,10 @@ private:
 
   std::vector<StringRef> SearchPaths;
   std::set<std::string> VisitedFiles;
+
+  // Driver is the owner of all opened files.
+  // InputFiles have MemoryBufferRefs to them.
+  std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
 };
 
 ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=238690&r1=238689&r2=238690&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Sun May 31 16:04:56 2015
@@ -46,14 +46,8 @@ std::string InputFile::getShortName() {
 }
 
 std::error_code ArchiveFile::parse() {
-  // Get a memory buffer.
-  auto MBOrErr = MemoryBuffer::getFile(Filename);
-  if (auto EC = MBOrErr.getError())
-    return EC;
-  MB = std::move(MBOrErr.get());
-
-  // Parse a memory buffer as an archive file.
-  auto ArchiveOrErr = Archive::create(MB->getMemBufferRef());
+  // Parse a MemoryBufferRef as an archive file.
+  auto ArchiveOrErr = Archive::create(MB);
   if (auto EC = ArchiveOrErr.getError())
     return EC;
   File = std::move(ArchiveOrErr.get());
@@ -89,17 +83,8 @@ ErrorOr<MemoryBufferRef> ArchiveFile::ge
 }
 
 std::error_code ObjectFile::parse() {
-  // MBRef is not initialized if this is not an archive member.
-  if (MBRef.getBuffer().empty()) {
-    auto MBOrErr = MemoryBuffer::getFile(Filename);
-    if (auto EC = MBOrErr.getError())
-      return EC;
-    MB = std::move(MBOrErr.get());
-    MBRef = MB->getMemBufferRef();
-  }
-
   // Parse a memory buffer as a COFF file.
-  auto BinOrErr = createBinary(MBRef);
+  auto BinOrErr = createBinary(MB);
   if (auto EC = BinOrErr.getError())
     return EC;
   std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
@@ -108,7 +93,7 @@ std::error_code ObjectFile::parse() {
     Bin.release();
     COFFObj.reset(Obj);
   } else {
-    return make_dynamic_error_code(Twine(Filename) + " is not a COFF file.");
+    return make_dynamic_error_code(getName() + " is not a COFF file.");
   }
 
   // Read section and symbol tables.
@@ -160,14 +145,14 @@ std::error_code ObjectFile::initializeSy
     // Get a COFFSymbolRef object.
     auto SymOrErr = COFFObj->getSymbol(I);
     if (auto EC = SymOrErr.getError())
-      return make_dynamic_error_code(Twine("broken object file: ") + Filename +
+      return make_dynamic_error_code("broken object file: " + getName() +
                                      ": " + EC.message());
     COFFSymbolRef Sym = SymOrErr.get();
 
     // Get a symbol name.
     StringRef SymbolName;
     if (auto EC = COFFObj->getSymbolName(Sym, SymbolName))
-      return make_dynamic_error_code(Twine("broken object file: ") + Filename +
+      return make_dynamic_error_code("broken object file: " + getName() +
                                      ": " + EC.message());
     // Skip special symbols.
     if (SymbolName == "@comp.id" || SymbolName == "@feat.00")
@@ -220,8 +205,8 @@ SymbolBody *ObjectFile::createSymbolBody
 }
 
 std::error_code ImportFile::parse() {
-  const char *Buf = MBRef.getBufferStart();
-  const char *End = MBRef.getBufferEnd();
+  const char *Buf = MB.getBufferStart();
+  const char *End = MB.getBufferEnd();
   const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf);
 
   // Check if the total size is valid.

Modified: lld/trunk/COFF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=238690&r1=238689&r2=238690&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.h (original)
+++ lld/trunk/COFF/InputFiles.h Sun May 31 16:04:56 2015
@@ -63,7 +63,7 @@ private:
 // .lib or .a file.
 class ArchiveFile : public InputFile {
 public:
-  explicit ArchiveFile(StringRef S) : InputFile(ArchiveKind), Filename(S) {}
+  explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind), MB(M) {}
   static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
   std::error_code parse() override;
   StringRef getName() override { return Filename; }
@@ -79,7 +79,7 @@ public:
 private:
   std::unique_ptr<Archive> File;
   std::string Filename;
-  std::unique_ptr<MemoryBuffer> MB;
+  MemoryBufferRef MB;
   std::vector<SymbolBody *> SymbolBodies;
   std::set<const char *> Seen;
   llvm::MallocAllocator Alloc;
@@ -88,13 +88,10 @@ private:
 // .obj or .o file. This may be a member of an archive file.
 class ObjectFile : public InputFile {
 public:
-  explicit ObjectFile(StringRef S) : InputFile(ObjectKind), Filename(S) {}
-  ObjectFile(StringRef S, MemoryBufferRef M)
-      : InputFile(ObjectKind), Filename(S), MBRef(M) {}
-
+  explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind), MB(M) {}
   static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
   std::error_code parse() override;
-  StringRef getName() override { return Filename; }
+  StringRef getName() override { return MB.getBufferIdentifier(); }
   std::vector<Chunk *> &getChunks() { return Chunks; }
   std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
 
@@ -115,10 +112,8 @@ private:
   SymbolBody *createSymbolBody(StringRef Name, COFFSymbolRef Sym,
                                const void *Aux, bool IsFirst);
 
-  std::string Filename;
   std::unique_ptr<COFFObjectFile> COFFObj;
-  std::unique_ptr<MemoryBuffer> MB;
-  MemoryBufferRef MBRef;
+  MemoryBufferRef MB;
   StringRef Directives;
   llvm::BumpPtrAllocator Alloc;
 
@@ -148,15 +143,15 @@ private:
 // for details about the format.
 class ImportFile : public InputFile {
 public:
-  explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind), MBRef(M) {}
+  explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind), MB(M) {}
   static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
-  StringRef getName() override { return MBRef.getBufferIdentifier(); }
+  StringRef getName() override { return MB.getBufferIdentifier(); }
   std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
 
 private:
   std::error_code parse() override;
 
-  MemoryBufferRef MBRef;
+  MemoryBufferRef MB;
   std::vector<SymbolBody *> SymbolBodies;
   llvm::BumpPtrAllocator Alloc;
   StringAllocator StringAlloc;

Modified: lld/trunk/COFF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=238690&r1=238689&r2=238690&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.cpp (original)
+++ lld/trunk/COFF/Symbols.cpp Sun May 31 16:04:56 2015
@@ -87,7 +87,7 @@ ErrorOr<std::unique_ptr<InputFile>> Lazy
   if (Magic != file_magic::coff_object)
     return make_dynamic_error_code("unknown file type");
 
-  std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef.getBufferIdentifier(), MBRef));
+  std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef));
   Obj->setParentName(File->getName());
   return std::move(Obj);
 }





More information about the llvm-commits mailing list