diff --git a/llvm/lib/Support/DynamicLibrary.cpp b/llvm/lib/Support/DynamicLibrary.cpp index 7b9d7abe7545d..319fbc59d43bb 100644 --- a/llvm/lib/Support/DynamicLibrary.cpp +++ b/llvm/lib/Support/DynamicLibrary.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/Config/config.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" #include @@ -107,12 +106,22 @@ class DynamicLibrary::HandleSet { }; namespace { -// Collection of symbol name/value pairs to be searched prior to any libraries. -static llvm::ManagedStatic> ExplicitSymbols; -// Collection of known library handles. -static llvm::ManagedStatic OpenedHandles; -// Lock for ExplicitSymbols and OpenedHandles. -static llvm::ManagedStatic> SymbolsMutex; + +struct Globals { + // Collection of symbol name/value pairs to be searched prior to any + // libraries. + llvm::StringMap ExplicitSymbols; + // Collection of known library handles. + DynamicLibrary::HandleSet OpenedHandles; + // Lock for ExplicitSymbols and OpenedHandles. + llvm::sys::SmartMutex SymbolsMutex; +}; + +Globals &getGlobals() { + static Globals G; + return G; +} + } // namespace #ifdef _WIN32 @@ -136,20 +145,18 @@ void *SearchForAddressOfSpecialSymbol(const char *SymbolName) { } // namespace llvm void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) { - SmartScopedLock Lock(*SymbolsMutex); - (*ExplicitSymbols)[SymbolName] = SymbolValue; + auto &G = getGlobals(); + SmartScopedLock Lock(G.SymbolsMutex); + G.ExplicitSymbols[SymbolName] = SymbolValue; } DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName, std::string *Err) { - // Force OpenedHandles to be added into the ManagedStatic list before any - // ManagedStatic can be added from static constructors in HandleSet::DLOpen. - HandleSet& HS = *OpenedHandles; - + auto &G = getGlobals(); void *Handle = HandleSet::DLOpen(FileName, Err); if (Handle != &Invalid) { - SmartScopedLock Lock(*SymbolsMutex); - HS.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr); + SmartScopedLock Lock(G.SymbolsMutex); + G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr); } return DynamicLibrary(Handle); @@ -157,9 +164,11 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName, DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle, std::string *Err) { - SmartScopedLock Lock(*SymbolsMutex); + auto &G = getGlobals(); + SmartScopedLock Lock(G.SymbolsMutex); // If we've already loaded this library, tell the caller. - if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false)) + if (!G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ false, + /*CanClose*/ false)) *Err = "Library already loaded"; return DynamicLibrary(Handle); @@ -173,21 +182,18 @@ void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) { void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) { { - SmartScopedLock Lock(*SymbolsMutex); + auto &G = getGlobals(); + SmartScopedLock Lock(G.SymbolsMutex); // First check symbols added via AddSymbol(). - if (ExplicitSymbols.isConstructed()) { - StringMap::iterator i = ExplicitSymbols->find(SymbolName); + StringMap::iterator i = G.ExplicitSymbols.find(SymbolName); - if (i != ExplicitSymbols->end()) - return i->second; - } + if (i != G.ExplicitSymbols.end()) + return i->second; // Now search the libraries. - if (OpenedHandles.isConstructed()) { - if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder)) - return Ptr; - } + if (void *Ptr = G.OpenedHandles.Lookup(SymbolName, SearchOrder)) + return Ptr; } return llvm::SearchForAddressOfSpecialSymbol(SymbolName); diff --git a/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp b/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp index 784b9c1bb2d27..74de1455a9960 100644 --- a/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp +++ b/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp @@ -9,7 +9,6 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "gtest/gtest.h" @@ -59,7 +58,6 @@ std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; } TEST(DynamicLibrary, Overload) { { std::string Err; - llvm_shutdown_obj Shutdown; DynamicLibrary DL = DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err); EXPECT_TRUE(DL.isValid()); @@ -107,68 +105,6 @@ TEST(DynamicLibrary, Overload) { EXPECT_EQ(GS, &OverloadTestA); EXPECT_EQ(StdString(GS()), "OverloadCall"); } - EXPECT_TRUE(FuncPtr(DynamicLibrary::SearchForAddressOfSymbol( - "TestA")) == nullptr); - - // Check serach ordering is reset to default after call to llvm_shutdown - EXPECT_EQ(DynamicLibrary::SearchOrder, DynamicLibrary::SO_Linker); -} - -TEST(DynamicLibrary, Shutdown) { - std::string A("PipSqueak"), B, C("SecondLib"); - std::vector Order; - { - std::string Err; - llvm_shutdown_obj Shutdown; - DynamicLibrary DL = - DynamicLibrary::getPermanentLibrary(LibPath(A).c_str(), &Err); - EXPECT_TRUE(DL.isValid()); - EXPECT_TRUE(Err.empty()); - - SetStrings SS_0 = FuncPtr( - DynamicLibrary::SearchForAddressOfSymbol("SetStrings")); - EXPECT_NE(SS_0, nullptr); - - SS_0(A, B); - EXPECT_EQ(B, "Local::Local(PipSqueak)"); - - TestOrder TO_0 = FuncPtr( - DynamicLibrary::SearchForAddressOfSymbol("TestOrder")); - EXPECT_NE(TO_0, nullptr); - - DynamicLibrary DL2 = - DynamicLibrary::getPermanentLibrary(LibPath(C).c_str(), &Err); - EXPECT_TRUE(DL2.isValid()); - EXPECT_TRUE(Err.empty()); - - // Should find latest version of symbols in SecondLib - SetStrings SS_1 = FuncPtr( - DynamicLibrary::SearchForAddressOfSymbol("SetStrings")); - EXPECT_NE(SS_1, nullptr); - EXPECT_NE(SS_0, SS_1); - - TestOrder TO_1 = FuncPtr( - DynamicLibrary::SearchForAddressOfSymbol("TestOrder")); - EXPECT_NE(TO_1, nullptr); - EXPECT_NE(TO_0, TO_1); - - B.clear(); - SS_1(C, B); - EXPECT_EQ(B, "Local::Local(SecondLib)"); - - TO_0(Order); - TO_1(Order); - } - EXPECT_EQ(A, "Global::~Global"); - EXPECT_EQ(B, "Local::~Local"); - EXPECT_EQ(FuncPtr( - DynamicLibrary::SearchForAddressOfSymbol("SetStrings")), - nullptr); - - // Test unload/destruction ordering - EXPECT_EQ(Order.size(), 2UL); - EXPECT_EQ(Order.front(), "SecondLib"); - EXPECT_EQ(Order.back(), "PipSqueak"); } #else