From fe12022b68e13f8aea7820edd85ac026e63c3105 Mon Sep 17 00:00:00 2001 From: roblabla Date: Tue, 6 Aug 2024 11:38:19 +0200 Subject: [PATCH] Make je_malloc_conf weak on MSVC Previously, the malloc_conf attribute wasn't as "weak" on MSVC as on other toolchain. While it is possible to override it in an OBJ file - in MSVC, every symbol coming from a LIB file can be overriden from an OBJ file - it isn't possible to override it from another lib file. This makes it impossible to override it from Rust, for instance, as it always generates libs and links them together, instead of linking the obj files directly. While the weak attribute is not supported by MSVC, it can be emulated using the /alternatename linker flag. This flag takes two symbols, and aliases the first symbol to the second if it isn't defined during linking. This ensures that the default value provided by jemalloc can be overridden from all contexts, whether the override comes from an obj or a lib, matching the behavior of gcc's weak attribute. This is supported by MSVC link.exe since time immemorial, and by lld-link since 3.7.0. --- src/jemalloc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/jemalloc.c b/src/jemalloc.c index abd7540f..cc6a6a23 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -28,12 +28,31 @@ /******************************************************************************/ /* Data. */ +#ifdef _MSC_VER +#define STR(s) #s +#define XSTR(s) STR(s) +#endif + /* Runtime configuration options. */ +#ifndef _MSC_VER const char *je_malloc_conf #ifndef _WIN32 JEMALLOC_ATTR(weak) #endif ; +#else +extern const char *je_malloc_conf; +const char *malloc_conf_default = NULL; +#if defined (_M_IX86) +// NOTE: The JEMALLOC_PRIVATE_NAMESPACE does not get applied properly on 32-bit +// windows, presumably due to the leading underscore being automatically added +// to all symbols. +#pragma comment(linker, "/alternatename:_" XSTR(je_malloc_conf) "=_malloc_conf_default") +#else +#pragma comment(linker, "/alternatename:" XSTR(je_malloc_conf) "=" XSTR(JEMALLOC_PRIVATE_NAMESPACE) "malloc_conf_default") +#endif +#endif + /* * The usual rule is that the closer to runtime you are, the higher priority * your configuration settings are (so the jemalloc config options get lower @@ -51,11 +70,24 @@ const char *je_malloc_conf * We don't actually want this to be widespread, so we'll give it a silly name * and not mention it in headers or documentation. */ +#ifndef _MSC_VER const char *je_malloc_conf_2_conf_harder #ifndef _WIN32 JEMALLOC_ATTR(weak) #endif ; +#else +extern const char *je_malloc_conf_2_conf_harder; +const char *malloc_conf_2_conf_harder_default = NULL; +#if defined (_M_IX86) +// NOTE: The JEMALLOC_PRIVATE_NAMESPACE does not get applied properly on 32-bit +// windows, presumably due to the leading underscore being automatically added +// to all symbols. +#pragma comment(linker, "/alternatename:_" XSTR(je_malloc_conf_2_conf_harder) "=_malloc_conf_2_conf_harder_default") +#else +#pragma comment(linker, "/alternatename:" XSTR(je_malloc_conf_2_conf_harder) "=" XSTR(JEMALLOC_PRIVATE_NAMESPACE) "malloc_conf_2_conf_harder_default") +#endif +#endif const char *opt_malloc_conf_symlink = NULL; const char *opt_malloc_conf_env_var = NULL;