Index: COFF/Chunks.h =================================================================== --- COFF/Chunks.h +++ COFF/Chunks.h @@ -413,7 +413,7 @@ size_t getSize() const override; void writeTo(uint8_t *buf) const override; - static MergeChunk *instances[Log2MaxSectionAlignment + 1]; + static LLVM_THREAD_LOCAL MergeChunk *instances[Log2MaxSectionAlignment + 1]; std::vector sections; private: Index: COFF/Chunks.cpp =================================================================== --- COFF/Chunks.cpp +++ COFF/Chunks.cpp @@ -860,7 +860,7 @@ } } -MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {}; +LLVM_THREAD_LOCAL MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {}; MergeChunk::MergeChunk(uint32_t alignment) : builder(StringTableBuilder::RAW, alignment) { Index: COFF/DebugTypes.cpp =================================================================== --- COFF/DebugTypes.cpp +++ COFF/DebugTypes.cpp @@ -46,7 +46,7 @@ static Expected findFromFile(const ObjFile *dependentFile); - static std::map> + static LLVM_THREAD_LOCAL std::map> instances; // The interface to the PDB (if it was opened successfully) @@ -90,7 +90,7 @@ }; } // namespace -static std::vector> GC; +static LLVM_THREAD_LOCAL std::vector> GC; TpiSource::TpiSource(TpiKind k, const ObjFile *f) : kind(k), file(f) { GC.push_back(std::unique_ptr(this)); @@ -131,7 +131,7 @@ } // namespace coff } // namespace lld -std::map> +LLVM_THREAD_LOCAL std::map> TypeServerSource::instances; // Make a PDB path assuming the PDB is in the same folder as the OBJ Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -55,7 +55,7 @@ namespace lld { namespace coff { -static Timer inputFileTimer("Input File Reading", Timer::root()); +static LLVM_THREAD_LOCAL Timer inputFileTimer("Input File Reading", Timer::root()); Configuration *config; LinkerDriver *driver; @@ -119,6 +119,7 @@ return !s.empty() && s.drop_back().endswith("crtend"); } +/* // ErrorOr is not default constructible, so it cannot be used as the type // parameter of a future. // FIXME: We could open the file in createFutureForFile and avoid needing to @@ -138,13 +139,13 @@ #endif return std::async(strategy, [=]() { auto mbOrErr = MemoryBuffer::getFile(path, - /*FileSize*/ -1, - /*RequiresNullTerminator*/ false); + -1, // FileSize + false); // RequiresNullTerminator if (!mbOrErr) return MBErrPair{nullptr, mbOrErr.getError()}; return MBErrPair{std::move(*mbOrErr), std::error_code()}; }); -} +}*/ // Symbol names are mangled by prepending "_" on x86. static StringRef mangle(StringRef sym) { @@ -227,14 +228,17 @@ } void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) { - auto future = - std::make_shared>(createFutureForFile(path)); + /*auto future = + std::make_shared>(createFutureForFile(path));*/ std::string pathStr = path; enqueueTask([=]() { - auto mbOrErr = future->get(); - if (mbOrErr.second) { + //auto mbOrErr = future->get(); + auto mbOrErr = MemoryBuffer::getFile(pathStr, + /*FileSize*/ -1, + /*RequiresNullTerminator*/ false); + if (!mbOrErr) { std::string msg = - "could not open '" + pathStr + "': " + mbOrErr.second.message(); + "could not open '" + pathStr + "': " + mbOrErr.getError().message(); // Check if the filename is a typo for an option flag. OptTable thinks // that all args that are not known options and that start with / are // filenames, but e.g. `/nodefaultlibs` is more likely a typo for @@ -246,7 +250,7 @@ else error(msg + "; did you mean '" + nearest + "'"); } else - driver->addBuffer(std::move(mbOrErr.first), wholeArchive, lazy); + driver->addBuffer(std::move(mbOrErr.get()), wholeArchive, lazy); }); } @@ -303,13 +307,16 @@ c.getFullName(), "could not get the filename for the member defining symbol " + toCOFFString(sym)); - auto future = std::make_shared>( - createFutureForFile(childName)); + /*auto future = std::make_shared>( + createFutureForFile(childName));*/ enqueueTask([=]() { - auto mbOrErr = future->get(); - if (mbOrErr.second) - reportBufferError(errorCodeToError(mbOrErr.second), childName); - driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), + //auto mbOrErr = future->get(); + auto mbOrErr = MemoryBuffer::getFile(childName, + /*FileSize*/ -1, + /*RequiresNullTerminator*/ false); + if (!mbOrErr) + reportBufferError(errorCodeToError(mbOrErr.getError()), childName); + driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.get())), toCOFFString(sym), parentName, /*OffsetInArchive=*/0); }); @@ -1116,7 +1123,7 @@ return; } - lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, true); + lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, false); if (args.hasArg(OPT_show_timing)) config->showTiming = true; Index: COFF/ICF.cpp =================================================================== --- COFF/ICF.cpp +++ COFF/ICF.cpp @@ -37,7 +37,7 @@ namespace lld { namespace coff { -static Timer icfTimer("ICF", Timer::root()); +static LLVM_THREAD_LOCAL Timer icfTimer("ICF", Timer::root()); class ICF { public: Index: COFF/InputFiles.h =================================================================== --- COFF/InputFiles.h +++ COFF/InputFiles.h @@ -163,7 +163,7 @@ bool isResourceObjFile() const { return !resourceChunks.empty(); } - static std::vector instances; + static LLVM_THREAD_LOCAL std::vector instances; // Flags in the absolute @feat.00 symbol if it is present. These usually // indicate if an object was compiled with certain security features enabled @@ -296,7 +296,7 @@ static bool classof(const InputFile *f) { return f->kind() == ImportKind; } - static std::vector instances; + static LLVM_THREAD_LOCAL std::vector instances; Symbol *impSym = nullptr; Symbol *thunkSym = nullptr; @@ -334,7 +334,7 @@ static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } ArrayRef getSymbols() { return symbols; } MachineTypes getMachineType() override; - static std::vector instances; + static LLVM_THREAD_LOCAL std::vector instances; std::unique_ptr obj; private: Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -49,9 +49,9 @@ namespace lld { namespace coff { -std::vector ObjFile::instances; -std::vector ImportFile::instances; -std::vector BitcodeFile::instances; +LLVM_THREAD_LOCAL std::vector ObjFile::instances; +LLVM_THREAD_LOCAL std::vector ImportFile::instances; +LLVM_THREAD_LOCAL std::vector BitcodeFile::instances; /// Checks that Source is compatible with being a weak alias to Target. /// If Source is Undefined and has no weak alias set, makes it a weak Index: COFF/MarkLive.cpp =================================================================== --- COFF/MarkLive.cpp +++ COFF/MarkLive.cpp @@ -15,7 +15,7 @@ namespace lld { namespace coff { -static Timer gctimer("GC", Timer::root()); +static LLVM_THREAD_LOCAL Timer gctimer("GC", Timer::root()); // Set live bit on for each reachable chunk. Unmarked (unreachable) // COMDAT chunks will be ignored by Writer, so they will be excluded Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -68,14 +68,14 @@ static ExitOnError exitOnErr; -static Timer totalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root()); +static LLVM_THREAD_LOCAL Timer totalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root()); -static Timer addObjectsTimer("Add Objects", totalPdbLinkTimer); -static Timer typeMergingTimer("Type Merging", addObjectsTimer); -static Timer symbolMergingTimer("Symbol Merging", addObjectsTimer); -static Timer globalsLayoutTimer("Globals Stream Layout", totalPdbLinkTimer); -static Timer tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer); -static Timer diskCommitTimer("Commit to Disk", totalPdbLinkTimer); +static LLVM_THREAD_LOCAL Timer addObjectsTimer("Add Objects", totalPdbLinkTimer); +static LLVM_THREAD_LOCAL Timer typeMergingTimer("Type Merging", addObjectsTimer); +static LLVM_THREAD_LOCAL Timer symbolMergingTimer("Symbol Merging", addObjectsTimer); +static LLVM_THREAD_LOCAL Timer globalsLayoutTimer("Globals Stream Layout", totalPdbLinkTimer); +static LLVM_THREAD_LOCAL Timer tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer); +static LLVM_THREAD_LOCAL Timer diskCommitTimer("Commit to Disk", totalPdbLinkTimer); namespace { class DebugSHandler; Index: COFF/SymbolTable.h =================================================================== --- COFF/SymbolTable.h +++ COFF/SymbolTable.h @@ -129,7 +129,7 @@ std::unique_ptr lto; }; -extern SymbolTable *symtab; +extern LLVM_THREAD_LOCAL SymbolTable *symtab; std::vector getSymbolLocations(ObjFile *file, uint32_t symIndex); Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -26,9 +26,9 @@ namespace lld { namespace coff { -static Timer ltoTimer("LTO", Timer::root()); +static LLVM_THREAD_LOCAL Timer ltoTimer("LTO", Timer::root()); -SymbolTable *symtab; +LLVM_THREAD_LOCAL SymbolTable *symtab; void SymbolTable::addFile(InputFile *file) { log("Reading " + toString(file)); Index: COFF/Symbols.h =================================================================== --- COFF/Symbols.h +++ COFF/Symbols.h @@ -232,7 +232,7 @@ // Section index relocations against absolute symbols resolve to // this 16 bit number, and it is the largest valid section index // plus one. This variable keeps it. - static uint16_t numOutputSections; + static LLVM_THREAD_LOCAL uint16_t numOutputSections; private: uint64_t va; Index: COFF/Symbols.cpp =================================================================== --- COFF/Symbols.cpp +++ COFF/Symbols.cpp @@ -106,7 +106,7 @@ return COFFSymbolRef(reinterpret_cast(sym)); } -uint16_t DefinedAbsolute::numOutputSections; +LLVM_THREAD_LOCAL uint16_t DefinedAbsolute::numOutputSections; static Chunk *makeImportThunk(DefinedImportData *s, uint16_t machine) { if (machine == AMD64) Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -80,7 +80,7 @@ // Global vector of all output sections. After output sections are finalized, // this can be indexed by Chunk::getOutputSection. -static std::vector outputSections; +static LLVM_THREAD_LOCAL std::vector outputSections; OutputSection *Chunk::getOutputSection() const { return osidx == 0 ? nullptr : outputSections[osidx - 1]; @@ -288,8 +288,8 @@ namespace lld { namespace coff { -static Timer codeLayoutTimer("Code Layout", Timer::root()); -static Timer diskCommitTimer("Commit Output File", Timer::root()); +static LLVM_THREAD_LOCAL Timer codeLayoutTimer("Code Layout", Timer::root()); +static LLVM_THREAD_LOCAL Timer diskCommitTimer("Commit Output File", Timer::root()); void writeResult() { Writer().run(); } Index: Common/ErrorHandler.cpp =================================================================== --- Common/ErrorHandler.cpp +++ Common/ErrorHandler.cpp @@ -60,7 +60,7 @@ outs().flush(); errs().flush(); - _exit(val); + sys::Process::ExitCurrentProcess(val); } void lld::diagnosticHandler(const DiagnosticInfo &di) { Index: Common/Memory.cpp =================================================================== --- Common/Memory.cpp +++ Common/Memory.cpp @@ -11,9 +11,9 @@ using namespace llvm; using namespace lld; -BumpPtrAllocator lld::bAlloc; -StringSaver lld::saver{bAlloc}; -std::vector lld::SpecificAllocBase::instances; +LLVM_THREAD_LOCAL BumpPtrAllocator lld::bAlloc; +LLVM_THREAD_LOCAL StringSaver lld::saver{bAlloc}; +LLVM_THREAD_LOCAL std::vector lld::SpecificAllocBase::instances; void lld::freeArena() { for (SpecificAllocBase *alloc : SpecificAllocBase::instances) Index: Common/Threads.cpp =================================================================== --- Common/Threads.cpp +++ Common/Threads.cpp @@ -8,4 +8,4 @@ #include "lld/Common/Threads.h" -bool lld::threadsEnabled = true; +bool lld::threadsEnabled = false; Index: Common/Timer.cpp =================================================================== --- Common/Timer.cpp +++ Common/Timer.cpp @@ -39,7 +39,7 @@ } Timer &Timer::root() { - static Timer rootTimer("Total Link Time"); + static LLVM_THREAD_LOCAL Timer rootTimer("Total Link Time"); return rootTimer; } Index: include/lld/Common/Memory.h =================================================================== --- include/lld/Common/Memory.h +++ include/lld/Common/Memory.h @@ -28,8 +28,8 @@ namespace lld { // Use this arena if your object doesn't have a destructor. -extern llvm::BumpPtrAllocator bAlloc; -extern llvm::StringSaver saver; +extern LLVM_THREAD_LOCAL llvm::BumpPtrAllocator bAlloc; +extern LLVM_THREAD_LOCAL llvm::StringSaver saver; void freeArena(); @@ -39,7 +39,7 @@ SpecificAllocBase() { instances.push_back(this); } virtual ~SpecificAllocBase() = default; virtual void reset() = 0; - static std::vector instances; + static LLVM_THREAD_LOCAL std::vector instances; }; template struct SpecificAlloc : public SpecificAllocBase {