diff options
author | Alexandre Ganea <alexandre.ganea@legionlabs.com> | 2022-01-15 21:47:54 -0500 |
---|---|---|
committer | Alexandre Ganea <alexandre.ganea@legionlabs.com> | 2022-01-16 08:57:57 -0500 |
commit | f860fe362282ed69b9d4503a20e5d20b9a041189 (patch) | |
tree | 1f85d88798f7bd31cae0059d71c3c7817333afd6 /lld/Common | |
parent | 070d1034da87c94d86d1a61245ecf068141fdf14 (diff) | |
download | llvm-f860fe362282ed69b9d4503a20e5d20b9a041189.tar.gz |
[LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.
See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html
Differential Revision: https://reviews.llvm.org/D108850
Diffstat (limited to 'lld/Common')
-rw-r--r-- | lld/Common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lld/Common/CommonLinkerContext.cpp | 41 | ||||
-rw-r--r-- | lld/Common/ErrorHandler.cpp | 69 | ||||
-rw-r--r-- | lld/Common/Memory.cpp | 19 | ||||
-rw-r--r-- | lld/Common/TargetOptionsCommandFlags.cpp | 3 |
5 files changed, 96 insertions, 37 deletions
diff --git a/lld/Common/CMakeLists.txt b/lld/Common/CMakeLists.txt index 9fdc67be7901..1ae7da1f5f7f 100644 --- a/lld/Common/CMakeLists.txt +++ b/lld/Common/CMakeLists.txt @@ -28,6 +28,7 @@ set_source_files_properties("${version_inc}" add_lld_library(lldCommon Args.cpp + CommonLinkerContext.cpp DWARF.cpp ErrorHandler.cpp Filesystem.cpp diff --git a/lld/Common/CommonLinkerContext.cpp b/lld/Common/CommonLinkerContext.cpp new file mode 100644 index 000000000000..75a58e84e03a --- /dev/null +++ b/lld/Common/CommonLinkerContext.cpp @@ -0,0 +1,41 @@ +//===- CommonLinkerContext.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lld/Common/CommonLinkerContext.h" +#include "lld/Common/ErrorHandler.h" +#include "lld/Common/Memory.h" + +using namespace llvm; +using namespace lld; + +// Reference to the current LLD instance. +static CommonLinkerContext *lctx; + +CommonLinkerContext::CommonLinkerContext() { lctx = this; } + +CommonLinkerContext::~CommonLinkerContext() { + assert(lctx); + // Explicitly call the destructors since we created the objects with placement + // new in SpecificAlloc::create(). + for (auto &it : instances) + it.second->~SpecificAllocBase(); + lctx = nullptr; +} + +CommonLinkerContext &lld::commonContext() { + assert(lctx); + return *lctx; +} + +bool lld::hasContext() { return lctx != nullptr; } + +void CommonLinkerContext::destroy() { + if (lctx == nullptr) + return; + delete lctx; +} diff --git a/lld/Common/ErrorHandler.cpp b/lld/Common/ErrorHandler.cpp index 399b6cac7547..15b3bd058ee9 100644 --- a/lld/Common/ErrorHandler.cpp +++ b/lld/Common/ErrorHandler.cpp @@ -10,6 +10,7 @@ #include "llvm/Support/Parallel.h" +#include "lld/Common/CommonLinkerContext.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" @@ -18,51 +19,69 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" -#include <mutex> #include <regex> using namespace llvm; using namespace lld; -// The functions defined in this file can be called from multiple threads, -// but lld::outs() or lld::errs() are not thread-safe. We protect them using a -// mutex. -static std::mutex mu; - -// We want to separate multi-line messages with a newline. `sep` is "\n" -// if the last messages was multi-line. Otherwise "". -static StringRef sep; - static StringRef getSeparator(const Twine &msg) { if (StringRef(msg.str()).contains('\n')) return "\n"; return ""; } -raw_ostream *lld::stdoutOS; -raw_ostream *lld::stderrOS; +ErrorHandler::~ErrorHandler() { + if (cleanupCallback) + cleanupCallback(); +} + +void ErrorHandler::initialize(llvm::raw_ostream &stdoutOS, + llvm::raw_ostream &stderrOS, bool exitEarly, + bool disableOutput) { + this->stdoutOS = &stdoutOS; + this->stderrOS = &stderrOS; + stderrOS.enable_colors(stderrOS.has_colors()); + this->exitEarly = exitEarly; + this->disableOutput = disableOutput; +} -ErrorHandler &lld::errorHandler() { - static ErrorHandler handler; - return handler; +void ErrorHandler::flushStreams() { + std::lock_guard<std::mutex> lock(mu); + outs().flush(); + errs().flush(); } +ErrorHandler &lld::errorHandler() { return context().e; } + raw_ostream &lld::outs() { - if (errorHandler().disableOutput) + ErrorHandler &e = errorHandler(); + return e.outs(); +} + +raw_ostream &lld::errs() { + ErrorHandler &e = errorHandler(); + return e.errs(); +} + +raw_ostream &ErrorHandler::outs() { + if (disableOutput) return llvm::nulls(); return stdoutOS ? *stdoutOS : llvm::outs(); } -raw_ostream &lld::errs() { - if (errorHandler().disableOutput) +raw_ostream &ErrorHandler::errs() { + if (disableOutput) return llvm::nulls(); return stderrOS ? *stderrOS : llvm::errs(); } void lld::exitLld(int val) { - // Delete any temporary file, while keeping the memory mapping open. - if (errorHandler().outputBuffer) - errorHandler().outputBuffer->discard(); + if (hasContext()) { + ErrorHandler &e = errorHandler(); + // Delete any temporary file, while keeping the memory mapping open. + if (e.outputBuffer) + e.outputBuffer->discard(); + } // Re-throw a possible signal or exception once/if it was catched by // safeLldMain(). @@ -75,11 +94,9 @@ void lld::exitLld(int val) { if (!CrashRecoveryContext::GetCurrent()) llvm_shutdown(); - { - std::lock_guard<std::mutex> lock(mu); - lld::outs().flush(); - lld::errs().flush(); - } + if (hasContext()) + lld::errorHandler().flushStreams(); + // When running inside safeLldMain(), restore the control flow back to the // CrashRecoveryContext. Otherwise simply use _exit(), meanning no cleanup, // since we want to avoid further crashes on shutdown. diff --git a/lld/Common/Memory.cpp b/lld/Common/Memory.cpp index c53e1d3e6cfc..7c90ff1d799c 100644 --- a/lld/Common/Memory.cpp +++ b/lld/Common/Memory.cpp @@ -7,16 +7,19 @@ //===----------------------------------------------------------------------===// #include "lld/Common/Memory.h" +#include "lld/Common/CommonLinkerContext.h" using namespace llvm; using namespace lld; -BumpPtrAllocator lld::bAlloc; -StringSaver lld::saver{bAlloc}; -std::vector<SpecificAllocBase *> lld::SpecificAllocBase::instances; - -void lld::freeArena() { - for (SpecificAllocBase *alloc : SpecificAllocBase::instances) - alloc->reset(); - bAlloc.Reset(); +SpecificAllocBase * +lld::SpecificAllocBase::getOrCreate(void *tag, size_t size, size_t align, + SpecificAllocBase *(&creator)(void *)) { + auto &instances = context().instances; + auto &instance = instances[tag]; + if (instance == nullptr) { + void *storage = context().bAlloc.Allocate(size, align); + instance = creator(storage); + } + return instance; } diff --git a/lld/Common/TargetOptionsCommandFlags.cpp b/lld/Common/TargetOptionsCommandFlags.cpp index d39477ed89ad..b7749c4a2032 100644 --- a/lld/Common/TargetOptionsCommandFlags.cpp +++ b/lld/Common/TargetOptionsCommandFlags.cpp @@ -7,12 +7,9 @@ //===----------------------------------------------------------------------===// #include "lld/Common/TargetOptionsCommandFlags.h" - #include "llvm/CodeGen/CommandFlags.h" #include "llvm/Target/TargetOptions.h" -static llvm::codegen::RegisterCodeGenFlags CGF; - llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() { return llvm::codegen::InitTargetOptionsFromCodeGenFlags(llvm::Triple()); } |