Index: lld/trunk/ELF/Driver.h =================================================================== --- lld/trunk/ELF/Driver.h +++ lld/trunk/ELF/Driver.h @@ -46,7 +46,7 @@ bool InLib = false; llvm::BumpPtrAllocator Alloc; - std::vector> Files; + std::vector Files; std::vector> OwningMBs; }; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -50,6 +50,7 @@ ScriptConfig = ≻ Driver->main(Args); + InputFile::freePool(); return !HasError; } @@ -127,7 +128,7 @@ MemoryBufferRef MBRef = *Buffer; if (Config->Binary && !KnownScript) { - Files.push_back(make_unique(MBRef)); + Files.push_back(new BinaryFile(MBRef)); return; } @@ -141,7 +142,7 @@ Files.push_back(createObjectFile(MB, Path)); return; } - Files.push_back(make_unique(MBRef)); + Files.push_back(new ArchiveFile(MBRef)); return; case file_magic::elf_shared_object: if (Config->Relocatable) { @@ -152,7 +153,7 @@ return; default: if (InLib) - Files.push_back(make_unique(MBRef)); + Files.push_back(new LazyObjectFile(MBRef)); else Files.push_back(createObjectFile(MBRef)); } @@ -570,7 +571,7 @@ // If -m was not given, infer it from object files. if (Config->EKind == ELFNoneKind) { - for (std::unique_ptr &F : Files) { + for (InputFile *F : Files) { if (F->EKind == ELFNoneKind) continue; Config->EKind = F->EKind; @@ -616,8 +617,8 @@ // Add all files to the symbol table. After this, the symbol table // contains all known names except a few linker-synthesized symbols. - for (std::unique_ptr &F : Files) - Symtab.addFile(std::move(F)); + for (InputFile *F : Files) + Symtab.addFile(F); // Add the start symbol. // It initializes either Config->Entry or Config->EntryAddr. @@ -658,8 +659,7 @@ // MergeInputSection::splitIntoPieces needs to be called before // any call of MergeInputSection::getOffset. Do that. - for (const std::unique_ptr> &F : - Symtab.getObjectFiles()) + for (elf::ObjectFile *F : Symtab.getObjectFiles()) { for (InputSectionBase *S : F->getSections()) { if (!S || S == &InputSection::Discarded || !S->Live) continue; @@ -668,6 +668,7 @@ if (auto *MS = dyn_cast>(S)) MS->splitIntoPieces(); } + } // Write the result to the file. writeResult(); Index: lld/trunk/ELF/ICF.cpp =================================================================== --- lld/trunk/ELF/ICF.cpp +++ lld/trunk/ELF/ICF.cpp @@ -148,8 +148,7 @@ template std::vector *> ICF::getSections() { std::vector *> V; - for (const std::unique_ptr> &F : - Symtab::X->getObjectFiles()) + for (ObjectFile *F : Symtab::X->getObjectFiles()) for (InputSectionBase *S : F->getSections()) if (isEligible(S)) V.push_back(cast>(S)); Index: lld/trunk/ELF/InputFiles.h =================================================================== --- lld/trunk/ELF/InputFiles.h +++ lld/trunk/ELF/InputFiles.h @@ -39,6 +39,8 @@ // The root class of input files. class InputFile { public: + virtual ~InputFile() = default; + enum Kind { ObjectKind, SharedKind, @@ -63,11 +65,19 @@ ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; + static void freePool(); + protected: - InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} + InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) { + Pool.push_back(this); + } private: const Kind FileKind; + + // All InputFile instances are added to the pool + // and freed all at once on exit by freePool(). + static std::vector Pool; }; // Returns "(internal)", "foo.a(bar.o)" or "baz.o". @@ -304,15 +314,14 @@ static bool classof(const InputFile *F) { return F->kind() == BinaryKind; } - template std::unique_ptr createELF(); + template InputFile *createELF(); private: std::vector ELFData; }; -std::unique_ptr createObjectFile(MemoryBufferRef MB, - StringRef ArchiveName = ""); -std::unique_ptr createSharedFile(MemoryBufferRef MB); +InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = ""); +InputFile *createSharedFile(MemoryBufferRef MB); } // namespace elf } // namespace lld Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -32,6 +32,17 @@ using namespace lld; using namespace lld::elf; +std::vector InputFile::Pool; + +// Deletes all InputFile instances created so far. +void InputFile::freePool() { + // Files are freed in reverse order so that files created + // from other files (e.g. object files extracted from archives) + // are freed in the proper order. + for (int I = Pool.size() - 1; I >= 0; --I) + delete Pool[I]; +} + // Returns "(internal)", "foo.a(bar.o)" or "baz.o". std::string elf::getFilename(const InputFile *F) { if (!F) @@ -700,31 +711,31 @@ } template