From 72b27a6a397404f7c1faff7813e26fd1f84b6183 Mon Sep 17 00:00:00 2001 From: Alexander Shaposhnikov Date: Tue, 11 Sep 2018 22:00:47 +0000 Subject: [PATCH] [object] Improve the performance of getSymbols used by ArchiveWriter In this diff we adjust the code of getSymbols to avoid creating LLVMContext when it's not necessary. Without this patch when the function getSymbols was called on a MachO object with a __bitcode section it was parsing the embedded bitcode and then ignoring the result. Test plan: make check-all Differential revision: https://reviews.llvm.org/D51759 llvm-svn: 341998 --- llvm/lib/Object/ArchiveWriter.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index ea17b22..ebb00f8 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -372,20 +372,32 @@ static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, static Expected> getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) { std::vector Ret; - LLVMContext Context; - Expected> ObjOrErr = - object::SymbolicFile::createSymbolicFile(Buf, llvm::file_magic::unknown, - &Context); - if (!ObjOrErr) { - // FIXME: check only for "not an object file" errors. - consumeError(ObjOrErr.takeError()); - return Ret; + // In the scenario when LLVMContext is populated SymbolicFile will contain a + // reference to it, thus SymbolicFile should be destroyed first. + LLVMContext Context; + std::unique_ptr Obj; + if (identify_magic(Buf.getBuffer()) == file_magic::bitcode) { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile( + Buf, file_magic::bitcode, &Context); + if (!ObjOrErr) { + // FIXME: check only for "not an object file" errors. + consumeError(ObjOrErr.takeError()); + return Ret; + } + Obj = std::move(*ObjOrErr); + } else { + auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf); + if (!ObjOrErr) { + // FIXME: check only for "not an object file" errors. + consumeError(ObjOrErr.takeError()); + return Ret; + } + Obj = std::move(*ObjOrErr); } HasObject = true; - object::SymbolicFile &Obj = *ObjOrErr.get(); - for (const object::BasicSymbolRef &S : Obj.symbols()) { + for (const object::BasicSymbolRef &S : Obj->symbols()) { if (!isArchiveSymbol(S)) continue; Ret.push_back(SymNames.tell()); @@ -470,7 +482,7 @@ Error llvm::writeArchive(StringRef ArcName, if (WriteSymtab) { uint64_t MaxOffset = 0; uint64_t LastOffset = MaxOffset; - for (const auto& M : Data) { + for (const auto &M : Data) { // Record the start of the member's offset LastOffset = MaxOffset; // Account for the size of each part associated with the member. -- 2.7.4