From 5c9e8f5e528704e6533a44f86acd542c80dec31b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 1 Nov 2016 21:06:40 +0000 Subject: [PATCH] Replace GAlloc with a template function. This patch replaces GAlloc::.Allocate() with alloc>(). Patch by Rui! llvm-svn: 285748 --- lld/ELF/Driver.cpp | 7 +++---- lld/ELF/InputFiles.cpp | 27 ++++++++------------------- lld/ELF/InputFiles.h | 27 +-------------------------- lld/ELF/Memory.cpp | 12 +++++++++++- lld/ELF/Memory.h | 24 ++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 489ab94..1171087 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -54,7 +54,6 @@ bool elf::link(ArrayRef Args, bool CanExitEarly, ScriptConfig = ≻ Driver->main(Args, CanExitEarly); - InputFile::freePool(); freeArena(); return !HasError; } @@ -132,7 +131,7 @@ void LinkerDriver::addFile(StringRef Path) { MemoryBufferRef MBRef = *Buffer; if (InBinary) { - Files.push_back(new BinaryFile(MBRef)); + Files.push_back(new (alloc()) BinaryFile(MBRef)); return; } @@ -146,7 +145,7 @@ void LinkerDriver::addFile(StringRef Path) { Files.push_back(createObjectFile(MB, Path)); return; } - Files.push_back(new ArchiveFile(MBRef)); + Files.push_back(new (alloc()) ArchiveFile(MBRef)); return; case file_magic::elf_shared_object: if (Config->Relocatable) { @@ -157,7 +156,7 @@ void LinkerDriver::addFile(StringRef Path) { return; default: if (InLib) - Files.push_back(new LazyObjectFile(MBRef)); + Files.push_back(new (alloc()) LazyObjectFile(MBRef)); else Files.push_back(createObjectFile(MBRef)); } diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index dadf3bb..041b41f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -35,7 +35,6 @@ using namespace llvm::sys::fs; using namespace lld; using namespace lld::elf; -std::vector InputFile::Pool; namespace { // In ELF object file all section addresses are zero. If we have multiple @@ -97,15 +96,6 @@ std::string DIHelper::getLineInfo(InputSectionBase *S, : ""; } -// 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) @@ -415,7 +405,7 @@ elf::ObjectFile::createInputSection(const Elf_Shdr &Sec) { // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. if (Config->Relocatable) - return new (GAlloc::IAlloc.Allocate()) + return new (alloc>()) InputSection(this, &Sec, Name); // Find the relocation target section and associate this @@ -458,14 +448,13 @@ elf::ObjectFile::createInputSection(const Elf_Shdr &Sec) { // .eh_frame_hdr section for runtime. So we handle them with a special // class. For relocatable outputs, they are just passed through. if (Name == ".eh_frame" && !Config->Relocatable) - return new (GAlloc::EHAlloc.Allocate()) + return new (alloc>()) EhInputSection(this, &Sec, Name); if (shouldMerge(Sec)) - return new (GAlloc::MAlloc.Allocate()) + return new (alloc>()) MergeInputSection(this, &Sec, Name); - return new (GAlloc::IAlloc.Allocate()) - InputSection(this, &Sec, Name); + return new (alloc>()) InputSection(this, &Sec, Name); } template void elf::ObjectFile::initializeSymbols() { @@ -834,13 +823,13 @@ static InputFile *createELFFile(MemoryBufferRef MB) { InputFile *Obj; if (Size == ELFCLASS32 && Endian == ELFDATA2LSB) - Obj = new T(MB); + Obj = new (alloc>()) T(MB); else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB) - Obj = new T(MB); + Obj = new (alloc>()) T(MB); else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB) - Obj = new T(MB); + Obj = new (alloc>()) T(MB); else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB) - Obj = new T(MB); + Obj = new (alloc>()) T(MB); else fatal("invalid file class: " + MB.getBufferIdentifier()); diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 0963634..f5da90d 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -37,21 +37,6 @@ class InputFile; namespace lld { namespace elf { -template struct GAlloc { - static llvm::SpecificBumpPtrAllocator> IAlloc; - static llvm::SpecificBumpPtrAllocator> MAlloc; - static llvm::SpecificBumpPtrAllocator> EHAlloc; -}; - -template -llvm::SpecificBumpPtrAllocator> GAlloc::IAlloc; - -template -llvm::SpecificBumpPtrAllocator> GAlloc::MAlloc; - -template -llvm::SpecificBumpPtrAllocator> GAlloc::EHAlloc; - using llvm::object::Archive; class InputFile; @@ -78,8 +63,6 @@ private: // The root class of input files. class InputFile { public: - virtual ~InputFile() = default; - enum Kind { ObjectKind, SharedKind, @@ -111,19 +94,11 @@ public: uint16_t EMachine = llvm::ELF::EM_NONE; uint8_t OSABI = 0; - static void freePool(); - protected: - InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) { - Pool.push_back(this); - } + InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} 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". diff --git a/lld/ELF/Memory.cpp b/lld/ELF/Memory.cpp index cc21aea..7771317 100644 --- a/lld/ELF/Memory.cpp +++ b/lld/ELF/Memory.cpp @@ -10,10 +10,20 @@ #include "Memory.h" using namespace llvm; +using namespace lld; +using namespace lld::elf; namespace lld { BumpPtrAllocator elf::BAlloc; StringSaver elf::Saver{elf::BAlloc}; -void elf::freeArena() { elf::BAlloc.Reset(); } +SpecificAllocBase::SpecificAllocBase() { Instances.push_back(this); } + +std::vector SpecificAllocBase::Instances; + +void elf::freeArena() { + for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) + Alloc->reset(); + BAlloc.Reset(); +} } diff --git a/lld/ELF/Memory.h b/lld/ELF/Memory.h index 6ac312b..b7cf18b 100644 --- a/lld/ELF/Memory.h +++ b/lld/ELF/Memory.h @@ -24,12 +24,36 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/StringSaver.h" +#include namespace lld { namespace elf { + +// Use this arena if your object doesn't have a destructor. extern llvm::BumpPtrAllocator BAlloc; extern llvm::StringSaver Saver; +// These two classes are hack to keep track of all +// SpecificBumpPtrAllocator instances. +struct SpecificAllocBase { + SpecificAllocBase(); + virtual ~SpecificAllocBase() = default; + virtual void reset() = 0; + static std::vector Instances; +}; + +template struct SpecificAlloc : public SpecificAllocBase { + void reset() override { Alloc.DestroyAll(); } + llvm::SpecificBumpPtrAllocator Alloc; +}; + +// Use this arean if your object have a destructor. +// Your destructor will be invoked from freeArena(). +template static T *alloc() { + static SpecificAlloc Alloc; + return Alloc.Alloc.Allocate(); +} + void freeArena(); } } -- 2.7.4