deps: Add jemalloc as an optional dependency

Jemalloc will be used if the cmake option `USE_JEMALLOC` is enabled(which is the
default). To avoid trouble with clang's ASAN, it is disabled by default if the
`SANITIZE` option is enabled.

Since jemalloc has thread cache for small objects, it fills the gap created by
removing klib memory pools.

The `xstrdup` funciton(memory.c) had to be reimplemented on top of `xmalloc` to
make it work with a custom allocator.
This commit is contained in:
Thiago de Arruda 2015-04-12 11:40:08 -03:00
parent 34c48aaf12
commit 8a1a9b9558
7 changed files with 116 additions and 20 deletions

View File

@ -202,6 +202,29 @@ option(LIBVTERM_USE_STATIC "Use static libvterm" ON)
find_package(LibVterm REQUIRED)
include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS})
option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF)
if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(WARNING "SANITIZE is only supported for Clang ... disabling")
set(SANITIZE OFF)
endif()
if(SANITIZE)
option(USE_JEMALLOC "Use jemalloc" OFF)
else()
option(USE_JEMALLOC "Use jemalloc" ON)
endif()
if(USE_JEMALLOC)
option(JEMALLOC_USE_STATIC "Use static jemalloc" ON)
find_package(JeMalloc)
if(JEMALLOC_FOUND)
message(STATUS "Using jemalloc instead of libc allocator")
include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS})
else()
set(USE_JEMALLOC OFF)
endif()
endif()
find_package(LibIntl)
if(LibIntl_FOUND)
include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS})

48
cmake/FindJeMalloc.cmake Normal file
View File

@ -0,0 +1,48 @@
# - Try to find jemalloc
# Once done this will define
# JEMALLOC_FOUND - System has jemalloc
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
find_package(PkgConfig)
if(NOT JEMALLOC_USE_BUNDLED)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
endif()
else()
set(PC_JEMALLOC_INCLUDEDIR)
set(PC_JEMALLOC_INCLUDE_DIRS)
set(PC_JEMALLOC_LIBDIR)
set(PC_JEMALLOC_LIBRARY_DIRS)
set(LIMIT_SEARCH NO_DEFAULT_PATH)
endif()
set(JEMALLOC_DEFINITIONS ${PC_JEMALLOC_CFLAGS_OTHER})
find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h
PATHS ${PC_JEMALLOC_INCLUDEDIR} ${PC_JEMALLOC_INCLUDE_DIRS}
${LIMIT_SEARCH})
# If we're asked to use static linkage, add libjemalloc.a as a preferred library name.
if(JEMALLOC_USE_STATIC)
list(APPEND JEMALLOC_NAMES
"${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
list(APPEND JEMALLOC_NAMES jemalloc)
find_library(JEMALLOC_LIBRARY NAMES ${JEMALLOC_NAMES}
HINTS ${PC_JEMALLOC_LIBDIR} ${PC_JEMALLOC_LIBRARY_DIRS}
${LIMIT_SEARCH})
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(JeMalloc DEFAULT_MSG
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)

View File

@ -65,5 +65,6 @@
#define FEAT_BROWSE
#define FEAT_CSCOPE
#define FEAT_MOUSE
#cmakedefine USE_JEMALLOC
#endif // AUTO_CONFIG_H

View File

@ -1,11 +1,5 @@
include(CheckLibraryExists)
option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF)
if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(WARNING "SANITIZE is only supported for Clang ... disabling")
set(SANITIZE OFF)
endif()
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua)
file(GLOB API_HEADERS api/*.h)
@ -176,9 +170,16 @@ list(APPEND NVIM_LINK_LIBRARIES
${CMAKE_THREAD_LIBS_INIT}
)
set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES})
if(USE_JEMALLOC)
# dont use jemalloc in the unit test library
list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES})
endif()
add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES}
${NEOVIM_HEADERS})
target_link_libraries(nvim ${NVIM_LINK_LIBRARIES})
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
install_helper(TARGETS nvim)
if(SANITIZE)
@ -199,5 +200,6 @@ set_property(TARGET libnvim APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB ")
add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES})
set_target_properties(nvim-test PROPERTIES COMPILE_FLAGS -DUNIT_TESTING)
add_subdirectory(po)

View File

@ -18,6 +18,14 @@
# include "memory.c.generated.h"
#endif
#if defined(USE_JEMALLOC) && !defined(UNIT_TESTING)
#include "jemalloc/jemalloc.h"
#define malloc(size) je_malloc(size)
#define calloc(count, size) je_calloc(count, size)
#define realloc(ptr, size) je_realloc(ptr, size)
#define free(ptr) je_free(ptr)
#endif
/// Try to free memory. Used when trying to recover from out of memory errors.
/// @see {xmalloc}
static void try_to_free_memory(void)
@ -368,19 +376,7 @@ size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
char *xstrdup(const char *str)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
{
char *ret = strdup(str);
if (!ret) {
try_to_free_memory();
ret = strdup(str);
if (!ret) {
mch_errmsg(e_outofmem);
mch_errmsg("\n");
preserve_exit();
}
}
return ret;
return xmemdupz(str, strlen(str));
}
/// A version of memchr that starts the search at `src + len`.

View File

@ -13,6 +13,7 @@ set(DEPS_DOWNLOAD_DIR "${DEPS_BUILD_DIR}/downloads")
option(USE_BUNDLED "Use bundled dependencies." ON)
option(USE_BUNDLED_JEMALLOC "Use the bundled jemalloc." ${USE_BUNDLED})
option(USE_BUNDLED_UNIBILIUM "Use the bundled unibilium." ${USE_BUNDLED})
option(USE_BUNDLED_LIBTERMKEY "Use the bundled libtermkey." ${USE_BUNDLED})
option(USE_BUNDLED_LIBVTERM "Use the bundled libvterm." ${USE_BUNDLED})
@ -73,6 +74,8 @@ set(LIBTERMKEY_SHA256 21846369081e6c9a0b615f4b3889c4cb809321c5ccc6e6c1640eb138f1
set(LIBVTERM_URL https://github.com/neovim/libvterm/archive/1b745d29d45623aa8d22a7b9288c7b0e331c7088.tar.gz)
set(LIBVTERM_SHA256 3fc75908256c0d158d6c2a32d39f34e86bfd26364f5404b7d9c03bb70cdc3611)
set(JEMALLOC_URL https://github.com/jemalloc/jemalloc/archive/3.6.0.tar.gz)
set(JEMALLOC_SHA256 68175f729423305dc8573cb093025a8db525e1956583c7c5924416a9abaaacb6)
if(USE_BUNDLED_UNIBILIUM)
include(BuildUnibilium)
@ -102,6 +105,10 @@ if(USE_BUNDLED_LUAROCKS)
include(BuildLuarocks)
endif()
if(USE_BUNDLED_JEMALLOC)
include(BuildJeMalloc)
endif()
add_custom_target(third-party ALL
COMMAND ${CMAKE_COMMAND} -E touch .third-party
DEPENDS ${THIRD_PARTY_DEPS})

19
third-party/cmake/BuildJeMalloc.cmake vendored Normal file
View File

@ -0,0 +1,19 @@
ExternalProject_Add(jemalloc
PREFIX ${DEPS_BUILD_DIR}
URL ${JEMALLOC_URL}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/jemalloc
DOWNLOAD_COMMAND ${CMAKE_COMMAND}
-DPREFIX=${DEPS_BUILD_DIR}
-DDOWNLOAD_DIR=${DEPS_DOWNLOAD_DIR}/jemalloc
-DURL=${JEMALLOC_URL}
-DEXPECTED_SHA256=${JEMALLOC_SHA256}
-DTARGET=jemalloc
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND sh ${DEPS_BUILD_DIR}/src/jemalloc/autogen.sh &&
${DEPS_BUILD_DIR}/src/jemalloc/configure --with-jemalloc-prefix=je_
--enable-cc-silence CC=${DEPS_C_COMPILER} --prefix=${DEPS_INSTALL_DIR}
BUILD_COMMAND ""
INSTALL_COMMAND ${MAKE_PRG} install_include install_lib)
list(APPEND THIRD_PARTY_DEPS jemalloc)