2021-09-03 13:31:05 +03:00
cmake_minimum_required ( VERSION 3.14 )
project ( snmalloc CXX )
2019-01-15 17:17:55 +03:00
2020-05-06 20:24:45 +03:00
if ( NOT CMAKE_BUILD_TYPE )
message ( STATUS "No build type selected, default to: Release" )
set ( CMAKE_BUILD_TYPE "Release" )
endif ( )
2020-03-20 12:17:38 +03:00
include ( CheckCXXCompilerFlag )
2021-09-03 13:31:05 +03:00
include ( CheckCXXSourceCompiles )
include ( CMakeDependentOption )
2020-03-20 12:17:38 +03:00
2021-09-03 13:31:05 +03:00
option ( SNMALLOC_HEADER_ONLY_LIBRARY "Use snmalloc has a header-only library" OFF )
# Options that apply globally
2019-01-15 17:17:55 +03:00
option ( USE_SNMALLOC_STATS "Track allocation stats" OFF )
2019-08-13 17:37:54 +03:00
option ( SNMALLOC_CI_BUILD "Disable features not sensible for CI" OFF )
2020-03-19 15:37:44 +03:00
option ( SNMALLOC_QEMU_WORKAROUND "Disable using madvise(DONT_NEED) to zero memory on Linux" Off )
2021-07-12 17:53:36 +03:00
option ( SNMALLOC_USE_CXX17 "Build as C++17 for legacy support." OFF )
2021-12-02 17:49:32 +03:00
option ( SNMALLOC_NO_REALLOCARRAY "Build without reallocarray exported" ON )
option ( SNMALLOC_NO_REALLOCARR "Build without reallocarr exported" ON )
2021-09-03 13:31:05 +03:00
# Options that apply only if we're not building the header-only library
cmake_dependent_option ( SNMALLOC_RUST_SUPPORT "Build static library for rust" OFF "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF )
cmake_dependent_option ( SNMALLOC_STATIC_LIBRARY "Build static libraries" ON "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF )
Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.
Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence. The snmalloc version has very slightly
lower median and worst-case times. This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.
The CI self-host job now uses the checked memcpy.
This also fixes an off-by-one error in the external bounds. This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.
In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.
The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace. This is also fixed.
The test involves hijacking `abort`, which doesn't work everywhere. It
also requires `backtrace` to work in configurations where stack traces
are enabled. This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.
For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes. These need to be made read-only, but this requires a PAL
change.
2021-08-10 13:36:53 +03:00
cmake_dependent_option ( SNMALLOC_MEMCPY_BOUNDS "Perform bounds checks on memcpy with heap objects" OFF "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF )
cmake_dependent_option ( SNMALLOC_CHECK_LOADS "Perform bounds checks on the source argument to memcpy with heap objects" OFF "SNMALLOC_MEMCPY_BOUNDS" OFF )
2021-09-03 13:31:05 +03:00
cmake_dependent_option ( SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE "Compile for current machine architecture" Off "NOT SNMALLOC_HEADER_ONLY_LIBRARY" OFF )
if ( NOT SNMALLOC_HEADER_ONLY_LIBRARY )
# Pick a sensible default for the thread cleanup mechanism
if ( ${ CMAKE_SYSTEM_NAME } STREQUAL FreeBSD )
set ( SNMALLOC_CLEANUP_DEFAULT THREAD_CLEANUP )
elseif ( UNIX AND NOT APPLE )
set ( SNMALLOC_CLEANUP_DEFAULT PTHREAD_DESTRUCTORS )
else ( )
set ( SNMALLOC_CLEANUP_DEFAULT CXX11_DESTRUCTORS )
endif ( )
# Specify the thread cleanup mechanism to use.
set ( SNMALLOC_CLEANUP ${ SNMALLOC_CLEANUP_DEFAULT } CACHE STRING "The mechanism that snmalloc will use for thread destructors. Valid options are: CXX11_DESTRUCTORS (use C++11 destructors, may depend on the C++ runtime library), PTHREAD_DESTRUCTORS (use pthreads, may interact badly with C++ on some platforms, such as macOS) THREAD_CLEANUP (depend on an explicit call to _malloc_thread_cleanup on thread exit, supported by FreeBSD's threading implementation and possibly elsewhere)" )
set_property ( CACHE SNMALLOC_CLEANUP PROPERTY STRINGS THREAD_CLEANUP PTHREAD_DESTRUCTORS CXX11_DESTRUCTORS )
set ( SNMALLOC_STATIC_LIBRARY_PREFIX "sn_" CACHE STRING "Static library function prefix" )
else ( )
unset ( SNMALLOC_STATIC_LIBRARY_PREFIX CACHE )
unset ( SNMALLOC_CLEANUP CACHE )
endif ( )
if ( NOT SNMALLOC_CLEANUP STREQUAL CXX11_DESTRUCTORS )
set ( CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "" )
endif ( )
# If CheckLinkerFlag doesn't exist then provide a dummy implementation that
# always fails. The fallback can be removed when we move to CMake 3.18 as the
# baseline.
include ( CheckLinkerFlag OPTIONAL RESULT_VARIABLE CHECK_LINKER_FLAG )
if ( NOT CHECK_LINKER_FLAG )
function ( check_linker_flag )
endfunction ( )
endif ( )
if ( NOT MSVC AND NOT ( SNMALLOC_CLEANUP STREQUAL CXX11_DESTRUCTORS ) )
# If the target compiler doesn't support -nostdlib++ then we must enable C at
# the global scope for the fallbacks to work.
check_linker_flag ( CXX "-nostdlib++" SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX )
if ( NOT SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX AND NOT SNMALLOC_HEADER_ONLY_LIBRARY )
enable_language ( C )
endif ( )
endif ( )
# Define a generator expression for things that will be enabled in either CI
# builds or debug mode.
set ( ci_or_debug "$<OR:$<BOOL:${SNMALLOC_CI_BUILD}>,$<CONFIG:Debug>>" )
2019-02-12 22:08:31 +03:00
2021-01-11 17:06:51 +03:00
# malloc.h will error if you include it on FreeBSD, so this test must not
# unconditionally include it.
2021-09-03 13:31:05 +03:00
CHECK_CXX_SOURCE_COMPILES ( "
2021-01-11 17:06:51 +03:00
#if __has_include(<malloc_np.h>)
#include <malloc_np.h>
2021-09-03 13:31:05 +03:00
#endif
2021-01-11 17:06:51 +03:00
#if __has_include(<malloc/malloc.h>)
#include <malloc/malloc.h>
#else
2020-04-18 09:58:13 +03:00
#include <malloc.h>
2021-01-11 17:06:51 +03:00
#endif
2020-04-18 09:58:13 +03:00
s i z e _ t malloc_usable_size ( const void* ptr ) { r e t u r n 0 ; }
i n t main ( ) { r e t u r n 0 ; }
" C O N S T _ Q U A L I F I E D _ M A L L O C _ U S A B L E _ S I Z E )
2021-09-03 13:31:05 +03:00
# Some libcs might not have getentropy, e.g. it appeared in glibc 2.25
2021-05-25 18:46:06 +03:00
# so we need to fallback if we cannot compile this
2021-09-03 13:31:05 +03:00
CHECK_CXX_SOURCE_COMPILES ( "
2021-05-25 18:46:06 +03:00
#if __has_include(<unistd.h>)
# include <unistd.h>
#endif
#if __has_include(<sys/random.h>)
2021-12-02 13:38:50 +03:00
# include <sys/random.h>
2021-05-25 18:46:06 +03:00
#endif
i n t main ( ) {
i n t e n t r o p y = 0 ;
i n t r e s = getentropy ( &entropy, sizeof(entropy ) ) ;
r e t u r n r e s ;
}
" S N M A L L O C _ P L A T F O R M _ H A S _ G E T E N T R O P Y )
2021-09-03 13:31:05 +03:00
# Provide as function so other projects can reuse
# FIXME: This modifies some variables that may or may not be the ones that
# provide flags and so is broken by design. It should be removed once Verona
# no longer uses it.
function ( warnings_high )
2019-05-09 14:32:32 +03:00
if ( MSVC )
# Force to always compile with W4
if ( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" )
string ( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
else ( )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
2019-01-15 17:17:55 +03:00
endif ( )
2021-07-12 17:53:36 +03:00
# /Wv18 is required for the annotation to force inline a lambda.
2019-05-09 14:32:32 +03:00
add_compile_options ( /WX /wd4127 /wd4324 /wd4201 )
2019-02-19 15:34:53 +03:00
else ( )
2019-05-09 14:32:32 +03:00
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
2021-02-24 15:54:14 +03:00
add_compile_options ( -Wsign-conversion -Wconversion )
2019-05-09 14:32:32 +03:00
endif ( )
2019-07-25 22:06:03 +03:00
add_compile_options ( -Wall -Wextra -Werror -Wundef )
2019-01-15 17:17:55 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
endfunction ( )
2019-01-15 17:17:55 +03:00
2021-09-03 13:31:05 +03:00
function ( clangformat_targets )
2019-05-22 15:20:43 +03:00
# The clang-format tool is installed under a variety of different names. Try
2020-02-06 12:09:32 +03:00
# to find a sensible one. Only look for versions 9 explicitly - we don't
2021-12-02 13:38:50 +03:00
# know whether our clang-format file will work with newer versions of the
2020-02-06 12:09:32 +03:00
# tool. It does not work with older versions as AfterCaseLabel is not supported
# in earlier versions.
2020-01-30 23:31:20 +03:00
find_program ( CLANG_FORMAT NAMES
2021-01-07 13:43:14 +03:00
c l a n g - f o r m a t 9 0 c l a n g - f o r m a t - 9 )
2019-05-22 15:20:43 +03:00
# If we've found a clang-format tool, generate a target for it, otherwise emit
# a warning.
if ( ${ CLANG_FORMAT } STREQUAL "CLANG_FORMAT-NOTFOUND" )
message ( WARNING "Not generating clangformat target, no clang-format tool found" )
else ( )
message ( STATUS "Generating clangformat target using ${CLANG_FORMAT}" )
2021-07-12 17:53:36 +03:00
file ( GLOB_RECURSE ALL_SOURCE_FILES CONFIGURE_DEPENDS src/*.cc src/*.h src/*.hh )
2020-09-02 14:41:09 +03:00
# clangformat does not yet understand concepts well; for the moment, don't
# ask it to format them. See https://reviews.llvm.org/D79773
2020-11-20 15:56:03 +03:00
list ( FILTER ALL_SOURCE_FILES EXCLUDE REGEX "src/[^/]*/[^/]*_concept\.h$" )
2019-05-22 15:20:43 +03:00
add_custom_target (
c l a n g f o r m a t
C O M M A N D $ { C L A N G _ F O R M A T }
- i
$ { A L L _ S O U R C E _ F I L E S } )
endif ( )
2021-09-03 13:31:05 +03:00
endfunction ( )
# The main target for snmalloc. This is the exported target for the
# header-only configuration and is used as a dependency for all of the builds
# that compile anything.
add_library ( snmalloc INTERFACE )
2019-05-22 15:20:43 +03:00
2021-07-12 17:53:36 +03:00
if ( SNMALLOC_USE_CXX17 )
2021-09-03 13:31:05 +03:00
target_compile_definitions ( snmalloc INTERFACE -DSNMALLOC_USE_CXX17 )
target_compile_features ( snmalloc INTERFACE cxx_std_17 )
2021-07-12 17:53:36 +03:00
else ( )
2021-09-03 13:31:05 +03:00
target_compile_features ( snmalloc INTERFACE cxx_std_20 )
2021-07-12 17:53:36 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
# Add header paths.
target_include_directories ( snmalloc
I N T E R F A C E
$ < I N S T A L L _ I N T E R F A C E : i n c l u d e / s n m a l l o c >
$ < B U I L D _ I N T E R F A C E : $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / s r c > )
2021-08-26 14:18:53 +03:00
2019-05-09 14:32:32 +03:00
if ( NOT MSVC )
2021-09-03 13:31:05 +03:00
find_package ( Threads REQUIRED COMPONENTS snmalloc )
target_link_libraries ( snmalloc INTERFACE
$ { C M A K E _ T H R E A D _ L I B S _ I N I T } $ < $ < C X X _ C O M P I L E R _ I D : G N U > : a t o m i c > )
2020-01-24 16:17:45 +03:00
endif ( )
if ( WIN32 )
2019-02-19 15:34:53 +03:00
set ( WIN8COMPAT FALSE CACHE BOOL "Avoid Windows 10 APIs" )
2021-09-03 13:31:05 +03:00
target_compile_definitions ( snmalloc INTERFACE $< $<BOOL:${WIN8COMPAT} > :WINVER=0x0603> )
# VirtualAlloc2 is exposed by mincore.lib, not Kernel32.lib (as the
# documentation says)
target_link_libraries ( snmalloc INTERFACE $< $<NOT:$<BOOL:${WIN8COMPAT} > >:mincore> )
message ( STATUS "snmalloc: Avoiding Windows 10 APIs is ${WIN8COMPAT}" )
2019-01-15 17:17:55 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
# Detect support for cmpxchg16b; Werror is needed to make sure mcx16 must be used by targets
2021-07-20 10:59:44 +03:00
check_cxx_compiler_flag ( "-Werror -Wextra -Wall -mcx16" SNMALLOC_COMPILER_SUPPORT_MCX16 )
if ( SNMALLOC_COMPILER_SUPPORT_MCX16 )
2021-09-03 13:31:05 +03:00
target_compile_options ( snmalloc INTERFACE $< $<COMPILE_LANGUAGE:CXX > :-mcx16> )
2021-07-20 10:59:44 +03:00
endif ( )
2020-01-24 16:17:45 +03:00
2021-09-03 13:31:05 +03:00
# Helper function that conditionally defines a macro for the build target if
# the CMake variable of the same name is set.
function ( add_as_define FLAG )
target_compile_definitions ( snmalloc INTERFACE $< $<BOOL:${${FLAG}} > : ${ FLAG } > )
endfunction ( )
add_as_define ( USE_SNMALLOC_STATS )
add_as_define ( SNMALLOC_QEMU_WORKAROUND )
add_as_define ( SNMALLOC_CI_BUILD )
add_as_define ( SNMALLOC_PLATFORM_HAS_GETENTROPY )
2021-12-02 17:49:32 +03:00
if ( SNMALLOC_NO_REALLOCARRAY )
add_as_define ( SNMALLOC_NO_REALLOCARRAY )
endif ( )
if ( SNMALLOC_NO_REALLOCARR )
add_as_define ( SNMALLOC_NO_REALLOCARR )
endif ( )
2021-12-02 13:38:50 +03:00
2021-09-03 13:31:05 +03:00
target_compile_definitions ( snmalloc INTERFACE $< $<BOOL:CONST_QUALIFIED_MALLOC_USABLE_SIZE > :MALLOC_USABLE_SIZE_QUALIFIER=const> )
# In debug and CI builds, link the backtrace library so that we can get stack
# traces on errors.
find_package ( Backtrace )
if ( ${ Backtrace_FOUND } )
target_compile_definitions ( snmalloc INTERFACE
$ < $ { c i _ o r _ d e b u g } : S N M A L L O C _ B A C K T R A C E _ H E A D E R = " $ { B a c k t r a c e _ H E A D E R } " > )
target_link_libraries ( snmalloc INTERFACE
$ < $ { c i _ o r _ d e b u g } : $ { B a c k t r a c e _ L I B R A R I E S } > )
target_include_directories ( snmalloc INTERFACE
$ < $ { c i _ o r _ d e b u g } : $ { B a c k t r a c e _ I N C L U D E _ D I R S } > )
2019-01-15 17:17:55 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
if ( MSVC )
target_compile_definitions ( snmalloc INTERFACE -D_HAS_EXCEPTIONS=0 )
else ( )
# All symbols are always dynamic on haiku and -rdynamic is redundant (and unsupported).
if ( NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku" )
# Get better stack traces in CI and debug builds.
target_link_options ( snmalloc INTERFACE $< ${ci_or_debug}:-rdynamic > )
endif ( )
2020-04-18 09:58:13 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
check_linker_flag ( CXX "-Wl,--no-undefined" SNMALLOC_LINKER_SUPPORT_NO_ALLOW_SHLIB_UNDEF )
2020-02-05 15:47:24 +03:00
2021-09-03 13:31:05 +03:00
function ( add_warning_flags name )
target_compile_options ( ${ name } PRIVATE
$ < $ < C X X _ C O M P I L E R _ I D : MSVC > : / Z i / W 4 / W X / w d 4 1 2 7 / w d 4 3 2 4 / w d 4 2 0 1 $ < $ { c i _ o r _ d e b u g } : / D E B U G > >
$ < $ < N O T : $ < O R : $ < C X X _ C O M P I L E R _ I D : MSVC > , $ < S T R E Q U A L : $ { C M A K E _ C X X _ S I M U L A T E _ I D } , MSVC > > > : - f n o - e x c e p t i o n s - f n o - r t t i - W a l l - W e x t r a - W e r r o r - W u n d e f >
$ < $ < C X X _ C O M P I L E R _ I D : C l a n g > : - W s i g n - c o n v e r s i o n - W c o n v e r s i o n > )
target_link_options ( ${ name } PRIVATE $< $<BOOL:${SNMALLOC_LINKER_SUPPORT_NO_ALLOW_SHLIB_UNDEF} > :-Wl,--no-undefined> )
endfunction ( )
2019-01-15 17:17:55 +03:00
2019-02-19 00:29:32 +03:00
2021-09-03 13:31:05 +03:00
# To build with just the header library target define SNMALLOC_HEADER_ONLY_LIBRARY
if ( NOT SNMALLOC_HEADER_ONLY_LIBRARY )
2020-03-20 12:17:38 +03:00
2021-09-03 13:31:05 +03:00
function ( subdirlist result curdir )
2021-07-12 17:53:36 +03:00
file ( GLOB children CONFIGURE_DEPENDS LIST_DIRECTORIES true RELATIVE ${ curdir } ${ curdir } /* )
2019-05-09 14:32:32 +03:00
set ( dirlist "" )
foreach ( child ${ children } )
if ( IS_DIRECTORY ${ curdir } / ${ child } )
list ( APPEND dirlist ${ child } )
endif ( )
endforeach ( )
2021-09-03 13:31:05 +03:00
set ( ${ result } ${ dirlist } PARENT_SCOPE )
endfunction ( )
2019-01-15 17:17:55 +03:00
2021-10-19 14:19:47 +03:00
if ( NOT ( DEFINED SNMALLOC_LINKER_FLAVOUR ) OR ( "${SNMALLOC_LINKER_FLAVOUR}" MATCHES "^$" ) )
# Linker not specified externally; probe to see if we can make lld work
set ( CMAKE_REQUIRED_LINK_OPTIONS -fuse-ld=lld )
check_cxx_source_compiles ( "int main() { return 1; }" LLD_WORKS )
if ( LLD_WORKS )
message ( STATUS "Using LLD to link snmalloc shims" )
endif ( )
elseif ( SNMALLOC_LINKER_FLAVOUR STREQUAL "lld" )
# Linker specified externally to be lld; assume it works and that the flags
# have also been set for us
set ( LLD_WORKS TRUE )
else ( )
# Linker specified externally as something other than lld; presume it
# doesn't work and don't add its flags, below
set ( LLD_WORKS FALSE )
2021-09-03 13:31:05 +03:00
endif ( )
2021-07-12 17:53:36 +03:00
2021-09-03 13:31:05 +03:00
function ( add_shim name type )
2020-01-23 10:08:18 +03:00
add_library ( ${ name } ${ type } ${ ARGN } )
2021-09-03 13:31:05 +03:00
target_link_libraries ( ${ name } snmalloc )
2019-05-09 14:32:32 +03:00
set_target_properties ( ${ name } PROPERTIES CXX_VISIBILITY_PRESET hidden )
2021-09-03 13:31:05 +03:00
target_compile_definitions ( ${ name } PRIVATE "SNMALLOC_USE_${SNMALLOC_CLEANUP}" )
2019-02-12 01:16:47 +03:00
2021-09-03 13:31:05 +03:00
add_warning_flags ( ${ name } )
2020-01-23 10:08:18 +03:00
if ( NOT MSVC )
2021-09-03 13:31:05 +03:00
target_compile_definitions ( ${ name } PRIVATE "SNMALLOC_EXPORT=__attribute__((visibility(\" default\ ")))" )
target_compile_options ( ${ name } PRIVATE
- f o m i t - f r a m e - p o i n t e r - f f u n c t i o n - s e c t i o n s )
# Static TLS model is unsupported on Haiku.
if ( NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku" )
target_compile_options ( ${ name } PRIVATE -ftls-model=initial-exec )
target_compile_options ( ${ name } PRIVATE $< $<BOOL:${SNMALLOC_CI_BUILD} > :-g> )
endif ( )
2021-07-12 17:53:36 +03:00
2021-09-03 13:31:05 +03:00
if ( SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE )
check_cxx_compiler_flag ( -march=native SUPPORT_MARCH_NATIVE )
if ( SUPPORT_MARCH_NATIVE )
target_compile_options ( ${ name } -march=native )
else ( )
message ( WARNING "Compiler does not support `-march=native` required by SNMALLOC_OPTIMISE_FOR_CURRENT_MACHINE" )
endif ( )
endif ( )
2021-07-12 17:53:36 +03:00
2021-09-03 13:31:05 +03:00
# Ensure that we do not link against C++ stdlib when compiling shims.
# If the compiler supports excluding the C++ stdlib implementation, use
# it. Otherwise, fall back to linking the library as if it were C, which
# has roughly the same effect.
if ( NOT ${ SNMALLOC_CLEANUP } STREQUAL CXX11_DESTRUCTORS )
check_linker_flag ( CXX "-nostdlib++" SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX )
if ( SNMALLOC_LINKER_SUPPORT_NOSTDLIBXX )
2021-10-20 11:31:45 +03:00
target_link_options ( ${ name } PRIVATE -nostdlib++ )
2021-09-03 13:31:05 +03:00
else ( )
set_target_properties ( ${ name } PROPERTIES LINKER_LANGUAGE C )
endif ( )
2021-07-12 17:53:36 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
# Remove all the duplicate new/malloc and free/delete definitions
target_link_options ( ${ name } PRIVATE $< $<BOOL:${LLD_WORKS} > :-Wl,--icf=all -fuse-ld=lld> )
2020-01-23 10:08:18 +03:00
endif ( )
2019-11-14 18:40:05 +03:00
Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.
Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence. The snmalloc version has very slightly
lower median and worst-case times. This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.
The CI self-host job now uses the checked memcpy.
This also fixes an off-by-one error in the external bounds. This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.
In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.
The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace. This is also fixed.
The test involves hijacking `abort`, which doesn't work everywhere. It
also requires `backtrace` to work in configurations where stack traces
are enabled. This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.
For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes. These need to be made read-only, but this requires a PAL
change.
2021-08-10 13:36:53 +03:00
target_compile_definitions ( ${ name } PRIVATE
S N M A L L O C _ C H E C K _ L O A D S = $ < I F : $ < B O O L : $ { S N M A L L O C _ C H E C K _ L O A D S } > , t r u e , f a l s e > )
2021-09-03 13:31:05 +03:00
install ( TARGETS ${ name } EXPORT snmallocConfig )
endfunction ( )
2019-05-09 14:32:32 +03:00
Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.
Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence. The snmalloc version has very slightly
lower median and worst-case times. This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.
The CI self-host job now uses the checked memcpy.
This also fixes an off-by-one error in the external bounds. This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.
In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.
The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace. This is also fixed.
The test involves hijacking `abort`, which doesn't work everywhere. It
also requires `backtrace` to work in configurations where stack traces
are enabled. This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.
For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes. These need to be made read-only, but this requires a PAL
change.
2021-08-10 13:36:53 +03:00
set ( SHIM_FILES src/override/new.cc )
if ( SNMALLOC_MEMCPY_BOUNDS )
list ( APPEND SHIM_FILES src/override/memcpy.cc )
endif ( )
2020-05-19 08:46:40 +03:00
if ( SNMALLOC_STATIC_LIBRARY )
Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.
Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence. The snmalloc version has very slightly
lower median and worst-case times. This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.
The CI self-host job now uses the checked memcpy.
This also fixes an off-by-one error in the external bounds. This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.
In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.
The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace. This is also fixed.
The test involves hijacking `abort`, which doesn't work everywhere. It
also requires `backtrace` to work in configurations where stack traces
are enabled. This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.
For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes. These need to be made read-only, but this requires a PAL
change.
2021-08-10 13:36:53 +03:00
add_shim ( snmallocshim-static STATIC ${ SHIM_FILES } )
2020-05-19 08:46:40 +03:00
target_compile_definitions ( snmallocshim-static PRIVATE
S N M A L L O C _ S T A T I C _ L I B R A R Y _ P R E F I X = $ { S N M A L L O C _ S T A T I C _ L I B R A R Y _ P R E F I X } )
endif ( )
2020-01-24 16:17:45 +03:00
if ( NOT WIN32 )
Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.
Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence. The snmalloc version has very slightly
lower median and worst-case times. This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.
The CI self-host job now uses the checked memcpy.
This also fixes an off-by-one error in the external bounds. This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.
In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.
The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace. This is also fixed.
The test involves hijacking `abort`, which doesn't work everywhere. It
also requires `backtrace` to work in configurations where stack traces
are enabled. This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.
For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes. These need to be made read-only, but this requires a PAL
change.
2021-08-10 13:36:53 +03:00
add_shim ( snmallocshim SHARED ${ SHIM_FILES } )
add_shim ( snmallocshim-checks SHARED ${ SHIM_FILES } )
2021-07-16 18:35:54 +03:00
target_compile_definitions ( snmallocshim-checks PRIVATE SNMALLOC_CHECK_CLIENT )
2019-05-09 14:32:32 +03:00
endif ( )
2020-01-23 10:08:18 +03:00
if ( SNMALLOC_RUST_SUPPORT )
add_shim ( snmallocshim-rust STATIC src/override/rust.cc )
2021-07-12 17:53:36 +03:00
add_shim ( snmallocshim-checks-rust STATIC src/override/rust.cc )
2021-07-16 18:35:54 +03:00
target_compile_definitions ( snmallocshim-checks-rust PRIVATE SNMALLOC_CHECK_CLIENT )
2020-01-23 10:08:18 +03:00
endif ( )
2019-05-09 14:32:32 +03:00
enable_testing ( )
set ( TESTDIR ${ CMAKE_CURRENT_SOURCE_DIR } /src/test )
subdirlist ( TEST_CATEGORIES ${ TESTDIR } )
list ( REVERSE TEST_CATEGORIES )
2021-09-03 13:31:05 +03:00
if ( ${ SNMALLOC_CLEANUP } STREQUAL THREAD_CLEANUP )
set ( TEST_CLEANUP PTHREAD_DESTRUCTORS )
else ( )
set ( TEST_CLEANUP ${ SNMALLOC_CLEANUP } )
endif ( )
2019-05-09 14:32:32 +03:00
foreach ( TEST_CATEGORY ${ TEST_CATEGORIES } )
2021-09-03 13:31:05 +03:00
message ( STATUS "Adding ${TEST_CATEGORY} tests" )
2019-05-09 14:32:32 +03:00
subdirlist ( TESTS ${ TESTDIR } / ${ TEST_CATEGORY } )
foreach ( TEST ${ TESTS } )
2020-09-28 12:08:19 +03:00
if ( WIN32
OR ( CMAKE_SYSTEM_NAME STREQUAL NetBSD )
2020-10-02 20:15:28 +03:00
OR ( CMAKE_SYSTEM_NAME STREQUAL OpenBSD )
2020-11-18 20:13:21 +03:00
OR ( CMAKE_SYSTEM_NAME STREQUAL DragonFly )
OR ( CMAKE_SYSTEM_NAME STREQUAL SunOS ) )
2020-09-28 12:08:19 +03:00
# Windows does not support aligned allocation well enough
# for pass through.
2020-10-02 20:15:28 +03:00
# NetBSD, OpenBSD and DragonFlyBSD do not support malloc*size calls.
2021-07-12 17:53:36 +03:00
set ( FLAVOURS fast;check )
2020-09-28 12:08:19 +03:00
else ( )
2021-08-26 12:04:44 +03:00
set ( FLAVOURS fast;check;malloc )
2020-09-28 12:08:19 +03:00
endif ( )
2021-03-24 19:12:22 +03:00
foreach ( FLAVOUR ${ FLAVOURS } )
2019-05-09 14:32:32 +03:00
unset ( SRC )
aux_source_directory ( ${ TESTDIR } / ${ TEST_CATEGORY } / ${ TEST } SRC )
2021-03-24 19:12:22 +03:00
set ( TESTNAME "${TEST_CATEGORY}-${TEST}-${FLAVOUR}" )
2019-05-09 14:32:32 +03:00
2019-08-13 12:56:54 +03:00
add_executable ( ${ TESTNAME } ${ SRC } )
2021-09-03 13:31:05 +03:00
add_warning_flags ( ${ TESTNAME } )
2021-02-19 12:07:42 +03:00
2021-03-24 19:12:22 +03:00
if ( ${ FLAVOUR } STREQUAL "malloc" )
2020-09-28 12:08:19 +03:00
target_compile_definitions ( ${ TESTNAME } PRIVATE SNMALLOC_PASS_THROUGH )
endif ( )
2021-03-24 19:12:22 +03:00
if ( ${ FLAVOUR } STREQUAL "check" )
2021-07-16 18:35:54 +03:00
target_compile_definitions ( ${ TESTNAME } PRIVATE SNMALLOC_CHECK_CLIENT )
2021-03-24 19:12:22 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
target_link_libraries ( ${ TESTNAME } snmalloc )
target_compile_definitions ( ${ TESTNAME } PRIVATE "SNMALLOC_USE_${TEST_CLEANUP}" )
2019-05-09 14:32:32 +03:00
if ( ${ TEST } MATCHES "release-.*" )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Adding test: ${TESTNAME} only for release configs" )
2019-05-09 14:32:32 +03:00
add_test ( NAME ${ TESTNAME } COMMAND ${ TESTNAME } CONFIGURATIONS "Release" )
else ( )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Adding test: ${TESTNAME}" )
2019-05-09 14:32:32 +03:00
add_test ( ${ TESTNAME } ${ TESTNAME } )
endif ( )
if ( ${ TEST_CATEGORY } MATCHES "perf" )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Single threaded test: ${TESTNAME}" )
2019-07-05 15:03:58 +03:00
set_tests_properties ( ${ TESTNAME } PROPERTIES PROCESSORS 4 )
2019-05-09 14:32:32 +03:00
endif ( )
2020-01-24 16:17:45 +03:00
if ( WIN32 )
2019-08-14 16:21:35 +03:00
# On Windows these tests use a lot of memory as it doesn't support
# lazy commit.
if ( ${ TEST } MATCHES "two_alloc_types" )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Single threaded test: ${TESTNAME}" )
2019-08-14 16:21:35 +03:00
set_tests_properties ( ${ TESTNAME } PROPERTIES PROCESSORS 4 )
endif ( )
if ( ${ TEST } MATCHES "fixed_region" )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Single threaded test: ${TESTNAME}" )
2019-08-14 16:21:35 +03:00
set_tests_properties ( ${ TESTNAME } PROPERTIES PROCESSORS 4 )
endif ( )
if ( ${ TEST } MATCHES "memory" )
2021-09-03 13:31:05 +03:00
message ( VERBOSE "Single threaded test: ${TESTNAME}" )
2019-08-14 16:21:35 +03:00
set_tests_properties ( ${ TESTNAME } PROPERTIES PROCESSORS 4 )
endif ( )
endif ( )
2021-07-12 17:53:36 +03:00
# if (${TEST_CATEGORY} MATCHES "func")
# target_compile_definitions(${TESTNAME} PRIVATE -DUSE_SNMALLOC_STATS)
# endif ()
2019-05-09 14:32:32 +03:00
endforeach ( )
2019-01-21 20:53:52 +03:00
endforeach ( )
2019-01-15 17:17:55 +03:00
endforeach ( )
2019-05-09 14:32:32 +03:00
2019-05-22 15:20:43 +03:00
clangformat_targets ( )
2019-05-18 13:54:35 +03:00
endif ( )
2021-09-03 13:31:05 +03:00
install ( TARGETS snmalloc EXPORT snmallocConfig )
install ( TARGETS EXPORT snmallocConfig DESTINATION ${ CMAKE_INSTALL_LIBDIR }
P U B L I C _ H E A D E R D E S T I N A T I O N $ { C M A K E _ I N S T A L L _ I N C L U D E D I R } / s n m a l l o c )
install ( DIRECTORY src/aal DESTINATION include/snmalloc )
install ( DIRECTORY src/ds DESTINATION include/snmalloc )
install ( DIRECTORY src/override DESTINATION include/snmalloc )
install ( DIRECTORY src/backend DESTINATION include/snmalloc )
install ( DIRECTORY src/mem DESTINATION include/snmalloc )
install ( DIRECTORY src/pal DESTINATION include/snmalloc )
2021-09-06 18:28:03 +03:00
install ( FILES
s r c / t e s t / m e a s u r e t i m e . h
s r c / t e s t / o p t . h
s r c / t e s t / s e t u p . h
s r c / t e s t / u s a g e . h
s r c / t e s t / x o r o s h i r o . h
D E S T I N A T I O N i n c l u d e / s n m a l l o c / t e s t
)
2021-09-03 13:31:05 +03:00
install ( FILES src/snmalloc.h;src/snmalloc_core.h;src/snmalloc_front.h DESTINATION include/snmalloc )
install ( EXPORT snmallocConfig
F I L E s n m a l l o c - c o n f i g . c m a k e
N A M E S P A C E s n m a l l o c : :
D E S T I N A T I O N " s h a r e / s n m a l l o c "
)