Commit 1a48bcd9 authored by Andrew Gallagher's avatar Andrew Gallagher Committed by Facebook Github Bot

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
parent b74eb888
......@@ -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
......@@ -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;
......
......@@ -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
......
......@@ -21,7 +21,7 @@ namespace detail {
template <typename T>
template <typename Tag, typename VaultTag>
SingletonHolder<T>& SingletonHolder<T>::singleton() {
static auto entry =
/* library-local */ static auto entry =
createGlobal<SingletonHolder<T>, std::pair<Tag, VaultTag>>([]() {
return new SingletonHolder<T>({typeid(T), typeid(Tag)},
*SingletonVault::singleton<VaultTag>());
......
......@@ -434,7 +434,7 @@ class SingletonVault {
// tests only.
template <typename VaultTag = detail::DefaultTag>
static SingletonVault* singleton() {
static SingletonVault* vault =
/* library-local */ static auto vault =
detail::createGlobal<SingletonVault, VaultTag>();
return vault;
}
......@@ -442,9 +442,8 @@ class SingletonVault {
typedef std::string(*StackTraceGetterPtr)();
static std::atomic<StackTraceGetterPtr>& stackTraceGetter() {
static std::atomic<StackTraceGetterPtr>* stackTraceGetterPtr =
detail::createGlobal<std::atomic<StackTraceGetterPtr>,
SingletonVault>();
/* library-local */ static auto stackTraceGetterPtr = detail::
createGlobal<std::atomic<StackTraceGetterPtr>, SingletonVault>();
return *stackTraceGetterPtr;
}
......@@ -657,7 +656,7 @@ class LeakySingleton {
};
static Entry& entryInstance() {
static auto entry = detail::createGlobal<Entry, Tag>();
/* library-local */ static auto entry = detail::createGlobal<Entry, Tag>();
return *entry;
}
......
......@@ -325,7 +325,7 @@ struct StaticMeta : StaticMetaBase {
static StaticMeta<Tag, AccessMode>& 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<StaticMeta<Tag, AccessMode>, void>();
return *instance;
}
......
......@@ -112,4 +112,13 @@ std::shared_ptr<RequestContext>& RequestContext::getStaticContext() {
return singleton.get();
}
RequestContext* RequestContext::get() {
auto context = getStaticContext();
if (!context) {
static RequestContext defaultContext;
return std::addressof(defaultContext);
}
return context.get();
}
}
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment