From d6e2bf2b3d233da537c9516b5062bd983e26f319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 24 Nov 2025 09:41:31 +0100 Subject: [PATCH] Use malloc_usable_size()/malloc_size() for memory accounting Restore usage of malloc_usable_size()/malloc_size(), but this time only for memory accounting and statistics purposes. This should reduce the memory footprint in case of compilation without jemalloc as we don't have to keep track of the allocated memory size ourselves. --- lib/isc/jemalloc_shim.h | 62 +++++++++++++++++++++++++++++++++++++++++ lib/isc/mem.c | 14 ++++++++++ meson.build | 26 +++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/lib/isc/jemalloc_shim.h b/lib/isc/jemalloc_shim.h index ef892f0318..d432917594 100644 --- a/lib/isc/jemalloc_shim.h +++ b/lib/isc/jemalloc_shim.h @@ -32,6 +32,66 @@ const char *malloc_conf = NULL; #define MALLOCX_ZERO ((int)0x40) #define MALLOCX_ZERO_GET(flags) ((bool)(flags & MALLOCX_ZERO)) +#if defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE) + +#ifdef HAVE_MALLOC_SIZE + +#include + +static inline size_t +sallocx(void *ptr, int flags ISC_ATTR_UNUSED) { + return malloc_size(ptr); +} + +#elif HAVE_MALLOC_USABLE_SIZE + +#ifdef __DragonFly__ +/* + * On DragonFly BSD 'man 3 malloc' advises us to include the following + * header to have access to malloc_usable_size(). + */ +#include +#else +#include +#endif + +static inline size_t +sallocx(void *ptr, int flags ISC_ATTR_UNUSED) { + return malloc_usable_size(ptr); +} + +#endif /* HAVE_MALLOC_SIZE */ + +static inline void * +mallocx(size_t size, int flags) { + void *ptr = malloc(size); + INSIST(ptr != NULL); + + if ((flags & MALLOCX_ZERO) != 0) { + memset(ptr, 0, size); + } + + return ptr; +} + +static inline void +sdallocx(void *ptr, size_t size ISC_ATTR_UNUSED, int flags ISC_ATTR_UNUSED) { + free(ptr); +} + +static inline void * +rallocx(void *ptr, size_t size, int flags) { + REQUIRE(size != 0); + REQUIRE((flags & MALLOCX_ZERO) == 0); + + ptr = realloc(ptr, size); + INSIST(ptr != NULL); + + return ptr; +} + +#else + typedef union { size_t size; max_align_t __alignment; @@ -85,4 +145,6 @@ rallocx(void *ptr, size_t size, int flags) { return ptr; } +#endif /* defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE) */ + #endif /* !defined(HAVE_JEMALLOC) */ diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 36498b3e8f..453aa71fba 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -724,7 +724,21 @@ isc__mem_reget(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size, DELETE_TRACE(ctx, old_ptr, old_size, func, file, line); mem_putstats(ctx, old_size); + ADJUST_ZERO_ALLOCATION_SIZE(new_size); + +#ifdef HAVE_JEMALLOC new_ptr = mem_realloc(ctx, old_ptr, new_size, flags); +#else + new_ptr = mem_realloc(ctx, old_ptr, new_size, + flags & ~ISC__MEM_ZERO); + + if ((flags & ISC__MEM_ZERO) != 0) { + if (new_size > old_size) { + memset((uint8_t *)new_ptr + old_size, 0, + new_size - old_size); + } + } +#endif mem_getstats(ctx, new_size); ADD_TRACE(ctx, new_ptr, new_size, func, file, line); diff --git a/meson.build b/meson.build index a4af8a153b..4315d697c6 100644 --- a/meson.build +++ b/meson.build @@ -718,6 +718,32 @@ if jemalloc_opt.allowed() endif endif +foreach fn : [ + 'malloc_usable_size', +] + if cc.has_function( + fn, + prefix: '#include ', + args: sys_defines, + dependencies: thread_dep, + ) + config.set('HAVE_@0@'.format(fn.to_upper()), 1) + endif +endforeach + +foreach fn : [ + 'malloc_size', +] + if cc.has_function( + fn, + prefix: '#include ', + args: sys_defines, + dependencies: thread_dep, + ) + config.set('HAVE_@0@'.format(fn.to_upper()), 1) + endif +endforeach + ## dnstap dnstap_dep = null_dep # Will be filled later