From 1a48bcd9c77353535820239dff3e7f5f7c1e93bb Mon Sep 17 00:00:00 2001 From: Andrew Gallagher Date: Tue, 18 Oct 2016 15:50:58 -0700 Subject: [PATCH] folly: fixes for use with `-fvisibility-inlines-hidden` Summary: - Annotate non-`const` static locals in inline functions which don't require a single copy be used globally at runtime. - Move implmentation from header file to source file (to avoid multiple copies at runtime). - Mark a non-stateful static local as `const` to it easy to ignore when searching for problematic static locals. Reviewed By: yfeldblum Differential Revision: D4010101 fbshipit-source-id: 3be94a5dc5b7029a26e11b2145c0d41968979a5c --- folly/CPortability.h | 27 +++++++++++++++++++++++++++ folly/Malloc.h | 2 +- folly/Portability.h | 12 ------------ folly/Singleton-inl.h | 2 +- folly/Singleton.h | 9 ++++----- folly/detail/ThreadLocalDetail.h | 2 +- folly/io/async/Request.cpp | 9 +++++++++ folly/io/async/Request.h | 9 +-------- 8 files changed, 44 insertions(+), 28 deletions(-) diff --git a/folly/CPortability.h b/folly/CPortability.h index 37d97382..5c497cb2 100644 --- a/folly/CPortability.h +++ b/folly/CPortability.h @@ -19,6 +19,20 @@ /* These definitions are in a separate file so that they * may be included from C- as well as C++-based projects. */ +/** + * Portable version check. + */ +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +/* nolint */ +# define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= \ + ((maj) << 16) + (min)) +# else +/* nolint */ +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + /* Define a convenience macro to test when address sanitizer is being used * across the different compilers (e.g. clang, gcc) */ #if defined(__clang__) @@ -80,3 +94,16 @@ #else # define UBSAN_DISABLE(x) #endif // UNDEFINED_SANITIZER + +/** + * Macro for marking functions as having public visibility. + */ +#if defined(__GNUC__) +# if __GNUC_PREREQ(4, 9) +# define FOLLY_EXPORT [[gnu::visibility("default")]] +# else +# define FOLLY_EXPORT __attribute__((__visibility__("default"))) +# endif +#else +# define FOLLY_EXPORT +#endif diff --git a/folly/Malloc.h b/folly/Malloc.h index 3aeb765c..5ff516bd 100644 --- a/folly/Malloc.h +++ b/folly/Malloc.h @@ -179,7 +179,7 @@ FOLLY_MALLOC_NOINLINE inline bool usingJEMalloc() noexcept { // Static because otherwise clever compilers will find out that // the ptr is not used and does not escape the scope, so they will // just optimize away the malloc. - static void* ptr = malloc(1); + static const void* ptr = malloc(1); if (!ptr) { // wtf, failing to allocate 1 byte return false; diff --git a/folly/Portability.h b/folly/Portability.h index ff144522..98ecd030 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -167,18 +167,6 @@ constexpr bool kHasUnalignedAccess = false; # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) #endif -// portable version check -#ifndef __GNUC_PREREQ -# if defined __GNUC__ && defined __GNUC_MINOR__ -/* nolint */ -# define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= \ - ((maj) << 16) + (min)) -# else -/* nolint */ -# define __GNUC_PREREQ(maj, min) 0 -# endif -#endif - #if defined(__GNUC__) && !defined(__APPLE__) && !__GNUC_PREREQ(4,9) // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019 // gcc 4.8.x incorrectly placed max_align_t in the root namespace diff --git a/folly/Singleton-inl.h b/folly/Singleton-inl.h index dad943be..19ed5c52 100644 --- a/folly/Singleton-inl.h +++ b/folly/Singleton-inl.h @@ -21,7 +21,7 @@ namespace detail { template template SingletonHolder& SingletonHolder::singleton() { - static auto entry = + /* library-local */ static auto entry = createGlobal, std::pair>([]() { return new SingletonHolder({typeid(T), typeid(Tag)}, *SingletonVault::singleton()); diff --git a/folly/Singleton.h b/folly/Singleton.h index 0539e280..c4640aff 100644 --- a/folly/Singleton.h +++ b/folly/Singleton.h @@ -434,7 +434,7 @@ class SingletonVault { // tests only. template static SingletonVault* singleton() { - static SingletonVault* vault = + /* library-local */ static auto vault = detail::createGlobal(); return vault; } @@ -442,9 +442,8 @@ class SingletonVault { typedef std::string(*StackTraceGetterPtr)(); static std::atomic& stackTraceGetter() { - static std::atomic* stackTraceGetterPtr = - detail::createGlobal, - SingletonVault>(); + /* library-local */ static auto stackTraceGetterPtr = detail:: + createGlobal, SingletonVault>(); return *stackTraceGetterPtr; } @@ -657,7 +656,7 @@ class LeakySingleton { }; static Entry& entryInstance() { - static auto entry = detail::createGlobal(); + /* library-local */ static auto entry = detail::createGlobal(); return *entry; } diff --git a/folly/detail/ThreadLocalDetail.h b/folly/detail/ThreadLocalDetail.h index fcd1a90f..c04fee1e 100644 --- a/folly/detail/ThreadLocalDetail.h +++ b/folly/detail/ThreadLocalDetail.h @@ -325,7 +325,7 @@ struct StaticMeta : StaticMetaBase { static StaticMeta& instance() { // Leak it on exit, there's only one per process and we don't have to // worry about synchronization with exiting threads. - static auto instance = + /* library-local */ static auto instance = detail::createGlobal, void>(); return *instance; } diff --git a/folly/io/async/Request.cpp b/folly/io/async/Request.cpp index 8d44a556..3babeea6 100644 --- a/folly/io/async/Request.cpp +++ b/folly/io/async/Request.cpp @@ -112,4 +112,13 @@ std::shared_ptr& RequestContext::getStaticContext() { return singleton.get(); } + +RequestContext* RequestContext::get() { + auto context = getStaticContext(); + if (!context) { + static RequestContext defaultContext; + return std::addressof(defaultContext); + } + return context.get(); +} } diff --git a/folly/io/async/Request.h b/folly/io/async/Request.h index 48252a2f..59d66f94 100644 --- a/folly/io/async/Request.h +++ b/folly/io/async/Request.h @@ -53,14 +53,7 @@ class RequestContext { } // Get the current context. - static RequestContext* get() { - auto context = getStaticContext(); - if (!context) { - static RequestContext defaultContext; - return std::addressof(defaultContext); - } - return context.get(); - } + static RequestContext* get(); // The following API may be used to set per-request data in a thread-safe way. // This access is still performance sensitive, so please ask if you need help -- 2.34.1