From 19d24e21568ec8e04da748dbe815f046a327f274 Mon Sep 17 00:00:00 2001 From: Giuseppe Ottaviano Date: Thu, 12 Nov 2015 08:37:48 -0800 Subject: [PATCH] Make Malloc.h self-contained Reviewed By: philippv Differential Revision: D2643313 fb-gh-sync-id: 10b9f735725ce47fab4bbfaa5972b3863357365f --- folly/Makefile.am | 1 - folly/Malloc.cpp | 65 ----------------------------------------------- folly/Malloc.h | 62 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 74 deletions(-) delete mode 100644 folly/Malloc.cpp diff --git a/folly/Makefile.am b/folly/Makefile.am index 4d5ac131..66390932 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -310,7 +310,6 @@ libfollybase_la_SOURCES = \ EscapeTables.cpp \ Format.cpp \ FormatTables.cpp \ - Malloc.cpp \ StringBase.cpp \ String.cpp \ Unicode.cpp diff --git a/folly/Malloc.cpp b/folly/Malloc.cpp deleted file mode 100644 index aa2175c7..00000000 --- a/folly/Malloc.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2015 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -namespace folly { - -// How do we determine that we're using jemalloc? -// In the hackiest way possible. We allocate memory using malloc() and see if -// the per-thread counter of allocated memory increases. This makes me feel -// dirty inside. Also note that this requires jemalloc to have been compiled -// with --enable-stats. -bool usingJEMallocSlow() { - // Some platforms (*cough* OSX *cough*) require weak symbol checks to be - // in the form if (mallctl != nullptr). Not if (mallctl) or if (!mallctl) - // (!!). http://goo.gl/xpmctm - if (mallocx == nullptr || rallocx == nullptr || xallocx == nullptr - || sallocx == nullptr || dallocx == nullptr || nallocx == nullptr - || mallctl == nullptr || mallctlnametomib == nullptr - || mallctlbymib == nullptr) { - return false; - } - - // "volatile" because gcc optimizes out the reads from *counter, because - // it "knows" malloc doesn't modify global state... - /* nolint */ volatile uint64_t* counter; - size_t counterLen = sizeof(uint64_t*); - - if (mallctl("thread.allocatedp", static_cast(&counter), &counterLen, - nullptr, 0) != 0) { - return false; - } - - if (counterLen != sizeof(uint64_t*)) { - return false; - } - - uint64_t origAllocated = *counter; - - void* ptr = malloc(1); - if (!ptr) { - // wtf, failing to allocate 1 byte - return false; - } - free(ptr); - - return (origAllocated != *counter); -} - -} // namespaces diff --git a/folly/Malloc.h b/folly/Malloc.h index dab215db..978cd133 100644 --- a/folly/Malloc.h +++ b/folly/Malloc.h @@ -32,8 +32,9 @@ #define MALLOCX_ZERO (static_cast(0x40)) #endif -// If using fbstring from libstdc++, then just define stub code -// here to typedef the fbstring type into the folly namespace. +// If using fbstring from libstdc++ (see comment in FBString.h), then +// just define stub code here to typedef the fbstring type into the +// folly namespace. // This provides backwards compatibility for code that explicitly // includes and uses fbstring. #if defined(_GLIBCXX_USE_FB) && !defined(_LIBSTDCXX_FBSTRING) @@ -86,7 +87,6 @@ __attribute__((__weak__)); #define FOLLY_HAVE_MALLOC_H 1 #else #include /* nolint */ -#include #endif // for malloc_usable_size @@ -100,6 +100,7 @@ __attribute__((__weak__)); #include #include +#include #include #include @@ -112,17 +113,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace folly { #endif -bool usingJEMallocSlow(); +// Cannot depend on Portability.h when _LIBSTDCXX_FBSTRING. +#ifdef __GNUC__ +#define FOLLY_MALLOC_NOINLINE __attribute__((__noinline__)) +#else +#define FOLLY_MALLOC_NOINLINE +#endif /** * Determine if we are using jemalloc or not. */ -inline bool usingJEMalloc() { +inline bool usingJEMalloc() noexcept { // Checking for rallocx != NULL is not sufficient; we may be in a dlopen()ed // module that depends on libjemalloc, so rallocx is resolved, but the main - // program might be using a different memory allocator. Look at the - // implementation of usingJEMallocSlow() for the (hacky) details. - static const bool result = usingJEMallocSlow(); + // program might be using a different memory allocator. + // How do we determine that we're using jemalloc? In the hackiest + // way possible. We allocate memory using malloc() and see if the + // per-thread counter of allocated memory increases. This makes me + // feel dirty inside. Also note that this requires jemalloc to have + // been compiled with --enable-stats. + static const bool result = [] () FOLLY_MALLOC_NOINLINE noexcept { + // Some platforms (*cough* OSX *cough*) require weak symbol checks to be + // in the form if (mallctl != nullptr). Not if (mallctl) or if (!mallctl) + // (!!). http://goo.gl/xpmctm + if (mallocx == nullptr || rallocx == nullptr || xallocx == nullptr + || sallocx == nullptr || dallocx == nullptr || nallocx == nullptr + || mallctl == nullptr || mallctlnametomib == nullptr + || mallctlbymib == nullptr) { + return false; + } + + // "volatile" because gcc optimizes out the reads from *counter, because + // it "knows" malloc doesn't modify global state... + /* nolint */ volatile uint64_t* counter; + size_t counterLen = sizeof(uint64_t*); + + if (mallctl("thread.allocatedp", static_cast(&counter), &counterLen, + nullptr, 0) != 0) { + return false; + } + + if (counterLen != sizeof(uint64_t*)) { + return false; + } + + uint64_t origAllocated = *counter; + + void* ptr = malloc(1); + if (!ptr) { + // wtf, failing to allocate 1 byte + return false; + } + free(ptr); + + return (origAllocated != *counter); + }(); + return result; } -- 2.34.1