From 236cac3d526ced0f60cb44344e4cbddc7331cb0f Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 24 Jun 2020 21:05:30 +0300 Subject: [PATCH] Fix jemalloc under OSX (by registering it as default zone explicitly) In case of OSX jemalloc register itself as a default zone allocator. But when you link statically then zone_register() will not be called, and even will be optimized out: $ nm clickhouse.patched | grep -c zone_register 0 Fix this, by manually calling it. v2: extern C --- contrib/jemalloc-cmake/CMakeLists.txt | 6 +++++- src/Common/new_delete.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/contrib/jemalloc-cmake/CMakeLists.txt b/contrib/jemalloc-cmake/CMakeLists.txt index 6de7d1ff124..79b351c3721 100644 --- a/contrib/jemalloc-cmake/CMakeLists.txt +++ b/contrib/jemalloc-cmake/CMakeLists.txt @@ -1,6 +1,6 @@ option (ENABLE_JEMALLOC "Enable jemalloc allocator" ${ENABLE_LIBRARIES}) -if (SANITIZE OR NOT (ARCH_AMD64 OR ARCH_ARM) OR NOT (OS_LINUX OR OS_FREEBSD)) +if (SANITIZE OR NOT (ARCH_AMD64 OR ARCH_ARM) OR NOT (OS_LINUX OR OS_FREEBSD OR OS_DARWIN)) set (ENABLE_JEMALLOC OFF) message (STATUS "jemalloc is disabled implicitly: it doesn't work with sanitizers and can only be used with x86_64 or aarch64 on linux or freebsd.") endif () @@ -148,6 +148,10 @@ if (ENABLE_JEMALLOC) endif () set_property(TARGET jemalloc APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USE_JEMALLOC=1) + if (MAKE_STATIC_LIBRARIES) + # To detect whether we need to register jemalloc for osx as default zone. + set_property(TARGET jemalloc APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS BUNDLED_STATIC_JEMALLOC=1) + endif() message (STATUS "Using jemalloc") else () diff --git a/src/Common/new_delete.cpp b/src/Common/new_delete.cpp index aa5f0cac7da..16663e100b7 100644 --- a/src/Common/new_delete.cpp +++ b/src/Common/new_delete.cpp @@ -10,6 +10,30 @@ # include #endif +#if defined(OS_DARWIN) && defined(BUNDLED_STATIC_JEMALLOC) +extern "C" +{ +extern void zone_register(); +} + +struct InitializeJemallocZoneAllocatorForOSX +{ + InitializeJemallocZoneAllocatorForOSX() + { + /// In case of OSX jemalloc register itself as a default zone allocator. + /// + /// But when you link statically then zone_register() will not be called, + /// and even will be optimized out: + /// + /// It is ok to call it twice (i.e. in case of shared libraries) + /// Since zone_register() is a no-op if the defualt zone is already replaced with something. + /// + /// https://github.com/jemalloc/jemalloc/issues/708 + zone_register(); + } +} initializeJemallocZoneAllocatorForOSX; +#endif + /// Replace default new/delete with memory tracking versions. /// @sa https://en.cppreference.com/w/cpp/memory/new/operator_new /// https://en.cppreference.com/w/cpp/memory/new/operator_delete