From c228ecefd8c183b5992aa9dd71922dff33a568b4 Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 18 Jul 2019 18:59:32 -0700 Subject: [PATCH] update for new dynamic direction on windows 64-bit --- ide/vs2017/mimalloc-override-test.vcxproj | 36 +++++++++- .../mimalloc-override-test.vcxproj.filters | 3 + ide/vs2017/mimalloc-override.vcxproj | 33 +++++++--- ide/vs2017/mimalloc-override.vcxproj.filters | 11 ++-- ide/vs2017/mimalloc.sln | 10 --- ide/vs2017/mimalloc.vcxproj | 4 ++ include/mimalloc-internal.h | 1 + include/mimalloc.h | 14 ++-- src/alloc-aligned.c | 11 ++++ src/alloc-override-win.c | 5 -- src/alloc-override.c | 3 +- src/alloc-posix.c | 11 ++++ src/alloc.c | 7 +- src/heap.c | 2 +- src/init.c | 66 +++++++++++++++---- src/memory.c | 1 + src/options.c | 50 ++++++++++---- test/main-override.c | 19 +++--- test/main-override.cpp | 19 +++--- 19 files changed, 218 insertions(+), 88 deletions(-) diff --git a/ide/vs2017/mimalloc-override-test.vcxproj b/ide/vs2017/mimalloc-override-test.vcxproj index c50f80dc..77752890 100644 --- a/ide/vs2017/mimalloc-override-test.vcxproj +++ b/ide/vs2017/mimalloc-override-test.vcxproj @@ -90,10 +90,18 @@ true ..\..\include MultiThreadedDebugDLL + false + Default + false Console + kernel32.lib;%(AdditionalDependencies) + + + COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + @@ -103,14 +111,20 @@ true ..\..\include MultiThreadedDebugDLL + false + Default + false Console - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - false + kernel32.lib;%(AdditionalDependencies) + + + COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + @@ -128,7 +142,11 @@ true true Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + @@ -150,9 +168,21 @@ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + COPY /Y $(SolutionDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + - + + true + true + true + true + + + false + false + diff --git a/ide/vs2017/mimalloc-override-test.vcxproj.filters b/ide/vs2017/mimalloc-override-test.vcxproj.filters index eb5e70b7..80f1c9c0 100644 --- a/ide/vs2017/mimalloc-override-test.vcxproj.filters +++ b/ide/vs2017/mimalloc-override-test.vcxproj.filters @@ -18,5 +18,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/ide/vs2017/mimalloc-override.vcxproj b/ide/vs2017/mimalloc-override.vcxproj index 5fe9f10e..5fad3cf1 100644 --- a/ide/vs2017/mimalloc-override.vcxproj +++ b/ide/vs2017/mimalloc-override.vcxproj @@ -70,21 +70,25 @@ $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .dll + mimalloc $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .dll + mimalloc $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .dll + mimalloc $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .dll + mimalloc @@ -96,6 +100,7 @@ MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;_MBCS;%(PreprocessorDefinitions); MultiThreadedDebugDLL false + Default @@ -106,8 +111,7 @@ - DllEntry - kernel32.lib;%(AdditionalDependencies) + ../../bin/mimalloc-redirect32.lib;%(AdditionalDependencies) @@ -124,6 +128,7 @@ MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;_MBCS;%(PreprocessorDefinitions); MultiThreadedDebugDLL false + Default @@ -134,8 +139,7 @@ - DllEntry - kernel32.lib;%(AdditionalDependencies) + ../../bin/mimalloc-redirect.lib;%(AdditionalDependencies) @@ -156,12 +160,12 @@ $(IntDir) false MultiThreadedDLL + Default true true - DllEntry - kernel32.lib;%(AdditionalDependencies) + ../../bin/mimalloc-redirect32.lib;%(AdditionalDependencies) @@ -188,12 +192,12 @@ $(IntDir) false MultiThreadedDLL + Default true true - DllEntry - kernel32.lib;%(AdditionalDependencies) + ../../bin/mimalloc-redirect.lib;%(AdditionalDependencies) @@ -219,7 +223,18 @@ false false - + + true + true + true + true + + + true + true + true + true + diff --git a/ide/vs2017/mimalloc-override.vcxproj.filters b/ide/vs2017/mimalloc-override.vcxproj.filters index d2892c32..a39667f3 100644 --- a/ide/vs2017/mimalloc-override.vcxproj.filters +++ b/ide/vs2017/mimalloc-override.vcxproj.filters @@ -46,9 +46,6 @@ Source Files - - Source Files - Source Files @@ -61,8 +58,14 @@ Source Files + + Source Files + Source Files + + Source Files + - + \ No newline at end of file diff --git a/ide/vs2017/mimalloc.sln b/ide/vs2017/mimalloc.sln index aeab6b88..f4860d93 100644 --- a/ide/vs2017/mimalloc.sln +++ b/ide/vs2017/mimalloc.sln @@ -11,8 +11,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimall EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -53,14 +51,6 @@ Global {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64 {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32 {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 - {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ide/vs2017/mimalloc.vcxproj b/ide/vs2017/mimalloc.vcxproj index bb1818b0..4a2069c6 100644 --- a/ide/vs2017/mimalloc.vcxproj +++ b/ide/vs2017/mimalloc.vcxproj @@ -70,21 +70,25 @@ $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .lib + mimalloc-static $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .lib + mimalloc-static $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .lib + mimalloc-static $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ .lib + mimalloc-static diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 3b45ada4..1d380e8f 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -35,6 +35,7 @@ bool _mi_is_main_thread(void); uintptr_t _mi_ptr_cookie(const void* p); uintptr_t _mi_random_shuffle(uintptr_t x); uintptr_t _mi_random_init(uintptr_t seed /* can be zero */); +bool _mi_preloading(); // true while the C runtime is not ready // os.c size_t _mi_os_page_size(void); diff --git a/include/mimalloc.h b/include/mimalloc.h index 3c10a65b..9828a6bb 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -197,6 +197,7 @@ mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_b mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; + // ------------------------------------------------------ // Convenience // ------------------------------------------------------ @@ -245,14 +246,15 @@ mi_decl_export void mi_option_set(mi_option_t option, long value); mi_decl_export void mi_option_set_default(mi_option_t option, long value); -// ---------------------------------------------------------------------------------- -// mi prefixed implementations of various posix, unix, and C++ allocation functions. -// ----------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------- +// mi prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. +// (This can be convenient when providing overrides of these functions.) +// -------------------------------------------------------------------------------------------- -mi_decl_export void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept; mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; +mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; mi_decl_export int mi__posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; @@ -263,6 +265,10 @@ mi_decl_export mi_decl_allocator void* mi_pvalloc(size_t size) mi_attr_noexcept mi_decl_export mi_decl_allocator void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_export mi_decl_allocator void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3); +mi_decl_export void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept; +mi_decl_export void* mi_aligned_recalloc(void* p, size_t size, size_t newcount, size_t alignment) mi_attr_noexcept; +mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t size, size_t newcount, size_t alignment, size_t offset) mi_attr_noexcept; + mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; diff --git a/src/alloc-aligned.c b/src/alloc-aligned.c index 3ef93c83..175fa3e3 100644 --- a/src/alloc-aligned.c +++ b/src/alloc-aligned.c @@ -150,3 +150,14 @@ void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t of void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { return mi_heap_realloc_aligned(mi_get_default_heap(), p, newsize, alignment); } + +void* mi_aligned_offset_recalloc(void* p, size_t size, size_t newcount, size_t alignment, size_t offset) mi_attr_noexcept { + size_t newsize; + if (mi_mul_overflow(size,newcount,&newsize)) return NULL; + return mi_heap_realloc_zero_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset, true ); +} +void* mi_aligned_recalloc(void* p, size_t size, size_t newcount, size_t alignment) mi_attr_noexcept { + size_t newsize; + if (mi_mul_overflow(size, newcount, &newsize)) return NULL; + return mi_heap_realloc_zero_aligned(mi_get_default_heap(), p, newsize, alignment, true ); +} diff --git a/src/alloc-override-win.c b/src/alloc-override-win.c index f0a5959a..7b0fe69f 100644 --- a/src/alloc-override-win.c +++ b/src/alloc-override-win.c @@ -98,11 +98,6 @@ static int __cdecl mi_setmaxstdio(int newmax); // Microsoft allocation extensions // ------------------------------------------------------ -static void* mi__expand(void* p, size_t newsize) { - void* res = mi_expand(p, newsize); - if (res == NULL) errno = ENOMEM; - return res; -} typedef size_t mi_nothrow_t; diff --git a/src/alloc-override.c b/src/alloc-override.c index 5ca88af7..5378850b 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -194,4 +194,5 @@ int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_me #pragma GCC visibility pop #endif -#endif // MI_MALLOC_OVERRIDE & !_WIN32 +#endif // MI_MALLOC_OVERRIDE && !_WIN32 + diff --git a/src/alloc-posix.c b/src/alloc-posix.c index b3185f15..3d28f655 100644 --- a/src/alloc-posix.c +++ b/src/alloc-posix.c @@ -80,3 +80,14 @@ void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { return newp; } +void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft + void* res = mi_expand(p, newsize); + if (res == NULL) errno = ENOMEM; + return res; +} + +void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { // Microsoft + size_t total; + if (mi_mul_overflow(count, size, &total)) return NULL; + return _mi_heap_realloc_zero(mi_get_default_heap(), p, total, true); +} diff --git a/src/alloc.c b/src/alloc.c index da8c69b9..10a74ce3 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -393,12 +393,6 @@ void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept { return mi_heap_realloc(mi_get_default_heap(),p,newsize); } -void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { - size_t total; - if (mi_mul_overflow(count, size, &total)) return NULL; - return _mi_heap_realloc_zero(mi_get_default_heap(),p,total,true); -} - void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept { return mi_heap_reallocn(mi_get_default_heap(),p,count,size); } @@ -537,6 +531,7 @@ std_new_handler_t mi_get_new_handler() { return _ZSt15get_new_handlerv(); } #else +// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`. std_new_handler_t mi_get_new_handler() { return NULL; } diff --git a/src/heap.c b/src/heap.c index 2b7b7a99..48bb9830 100644 --- a/src/heap.c +++ b/src/heap.c @@ -172,7 +172,7 @@ void mi_collect(bool force) mi_attr_noexcept { ----------------------------------------------------------- */ mi_heap_t* mi_heap_get_default(void) { - mi_thread_init(); + // mi_thread_init(); return mi_get_default_heap(); } diff --git a/src/init.c b/src/init.c index f55b7318..06aa28c5 100644 --- a/src/init.c +++ b/src/init.c @@ -373,6 +373,47 @@ void mi_thread_done(void) mi_attr_noexcept { // -------------------------------------------------------- static void mi_process_done(void); +static bool os_preloading = true; // true until this module is initialized +static bool mi_redirected = false; // true if malloc redirects to mi_malloc + +// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false. +bool _mi_preloading() { + return os_preloading; +} + +// Communicate with the redirection module on Windows +#if defined(_WIN32) && defined(MI_SHARED_LIB) +mi_decl_export void _mi_redirect_init() { + // called on redirection + mi_redirected = true; +} +__declspec(dllimport) bool mi_allocator_init(const char** message); +__declspec(dllimport) void mi_allocator_done(); +#else +static bool mi_allocator_init(const char** message) { + if (message != NULL) *message = NULL; + return true; +} +static void mi_allocator_done() { + // nothing to do +} +#endif + +// Called once by the process loader +static void mi_process_load(void) { + os_preloading = false; + atexit(&mi_process_done); + mi_process_init(); + //mi_stats_reset(); + if (mi_redirected) _mi_verbose_message("malloc is redirected.\n"); + + // show message from the redirector (if present) + const char* msg = NULL; + mi_allocator_init(&msg); + if (msg != NULL) _mi_verbose_message(msg); +} + +// Initialize the process; called by thread_init or the process loader void mi_process_init(void) mi_attr_noexcept { // ensure we are called once if (_mi_process_is_initialized) return; @@ -381,7 +422,7 @@ void mi_process_init(void) mi_attr_noexcept { // when using dynamic linking with interpose. mi_heap_t* h = _mi_heap_default; _mi_process_is_initialized = true; - + _mi_heap_main.thread_id = _mi_thread_id(); _mi_verbose_message("process init: 0x%zx\n", _mi_heap_main.thread_id); uintptr_t random = _mi_random_init(_mi_heap_main.thread_id) ^ (uintptr_t)h; @@ -389,15 +430,16 @@ void mi_process_init(void) mi_attr_noexcept { _mi_heap_main.cookie = (uintptr_t)&_mi_heap_main ^ random; #endif _mi_heap_main.random = _mi_random_shuffle(random); + mi_process_setup_auto_thread_done(); + _mi_os_init(); #if (MI_DEBUG) _mi_verbose_message("debug level : %d\n", MI_DEBUG); #endif - atexit(&mi_process_done); - mi_process_setup_auto_thread_done(); - mi_stats_reset(); - _mi_os_init(); + mi_thread_init(); + mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) } +// Called when the process is done (through `at_exit`) static void mi_process_done(void) { // only shutdown if we were initialized if (!_mi_process_is_initialized) return; @@ -413,7 +455,9 @@ static void mi_process_done(void) { mi_option_is_enabled(mi_option_verbose)) { mi_stats_print(NULL); } + mi_allocator_done(); _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); + os_preloading = true; // don't call the C runtime anymore } @@ -425,8 +469,8 @@ static void mi_process_done(void) { __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { UNUSED(reserved); UNUSED(inst); - if (reason==DLL_PROCESS_ATTACH) { - mi_process_init(); + if (reason==DLL_PROCESS_ATTACH) { + mi_process_load(); } else if (reason==DLL_THREAD_DETACH) { mi_thread_done(); @@ -437,7 +481,7 @@ static void mi_process_done(void) { #elif defined(__cplusplus) // C++: use static initialization to detect process start static bool _mi_process_init(void) { - mi_process_init(); + mi_process_load(); return (_mi_heap_main.thread_id != 0); } static bool mi_initialized = _mi_process_init(); @@ -445,14 +489,14 @@ static void mi_process_done(void) { #elif defined(__GNUC__) || defined(__clang__) // GCC,Clang: use the constructor attribute static void __attribute__((constructor)) _mi_process_init(void) { - mi_process_init(); + mi_process_load(); } #elif defined(_MSC_VER) // MSVC: use data section magic for static libraries // See static int _mi_process_init(void) { - mi_process_init(); + mi_process_load(); return 0; } typedef int(*_crt_cb)(void); @@ -467,5 +511,5 @@ static void mi_process_done(void) { #pragma data_seg() #else -#pragma message("define a way to call mi_process_init/done on your platform") +#pragma message("define a way to call mi_process_load on your platform") #endif diff --git a/src/memory.c b/src/memory.c index 83e90b0d..74a9628c 100644 --- a/src/memory.c +++ b/src/memory.c @@ -114,6 +114,7 @@ bool mi_is_in_heap_region(const void* p) { return false; } + /* ---------------------------------------------------------------------------- Commit from a region -----------------------------------------------------------------------------*/ diff --git a/src/options.c b/src/options.c index ac0910a0..36997d80 100644 --- a/src/options.c +++ b/src/options.c @@ -16,6 +16,10 @@ int mi_version(void) mi_attr_noexcept { return MI_MALLOC_VERSION; } +#ifdef _WIN32 +#include +#endif + // -------------------------------------------------------- // Options // -------------------------------------------------------- @@ -31,7 +35,7 @@ typedef struct mi_option_desc_s { const char* name; // option name without `mimalloc_` prefix } mi_option_desc_t; -static mi_option_desc_t options[_mi_option_last] = +static mi_option_desc_t options[_mi_option_last] = { // stable options { 0, UNINIT, "show_stats" }, @@ -41,15 +45,15 @@ static mi_option_desc_t options[_mi_option_last] = // the following options are experimental and not all combinations make sense. { 0, UNINIT, "page_reset" }, { 0, UNINIT, "cache_reset" }, - { 1, UNINIT, "eager_commit" }, - { 1, UNINIT, "eager_region_commit" }, // eager_commit should be on when eager_region_commit is on + { 1, UNINIT, "eager_commit" }, + { 1, UNINIT, "eager_region_commit" }, // eager_commit should be on when eager_region_commit is on { 0, UNINIT, "large_os_pages" }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's - { 0, UNINIT, "reset_decommits" }, - { 0, UNINIT, "reset_discards" }, + { 0, UNINIT, "reset_decommits" }, + { 0, UNINIT, "reset_discards" }, #if MI_SECURE { MI_SECURE, INITIALIZED, "secure" } // in a secure build the environment setting is ignored #else - { 0, UNINIT, "secure" } + { 0, UNINIT, "secure" } #endif }; @@ -104,7 +108,17 @@ static void mi_vfprintf( FILE* out, const char* prefix, const char* fmt, va_list char buf[256]; if (fmt==NULL) return; if (out==NULL) out = stdout; + if (_mi_preloading()) return; vsnprintf(buf,sizeof(buf)-1,fmt,args); + #ifdef _WIN32 + // on windows with redirection, the C runtime uses us and we cannot call `fputs` + // while called from the C runtime itself, so use a non-locking option + if (out==stderr) { + if (prefix != NULL) _cputs(prefix); + _cputs(buf); + return; + } + #endif if (prefix != NULL) fputs(prefix,out); fputs(buf,out); } @@ -174,21 +188,29 @@ static void mi_strlcat(char* dest, const char* src, size_t dest_size) { dest[dest_size - 1] = 0; } -static void mi_option_init(mi_option_desc_t* desc) { - desc->init = DEFAULTED; - // Read option value from the environment - char buf[32]; - mi_strlcpy(buf, "mimalloc_", sizeof(buf)); - mi_strlcat(buf, desc->name, sizeof(buf)); +static const char* mi_getenv(const char* name) { + if (_mi_preloading()) return NULL; // don't call getenv too early #pragma warning(suppress:4996) - char* s = getenv(buf); + const char* s = getenv(name); if (s == NULL) { + char buf[64+1]; + strncpy_s(buf,64,name,64); buf[64] = 0; for (size_t i = 0; i < strlen(buf); i++) { - buf[i] = toupper(buf[i]); + buf[i] = toupper(name[i]); } #pragma warning(suppress:4996) s = getenv(buf); } + return s; +} + +static void mi_option_init(mi_option_desc_t* desc) { + if (!_mi_preloading()) desc->init = DEFAULTED; + // Read option value from the environment + char buf[64]; + mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + mi_strlcat(buf, desc->name, sizeof(buf)); + const char* s = mi_getenv(buf); if (s != NULL) { mi_strlcpy(buf, s, sizeof(buf)); for (size_t i = 0; i < strlen(buf); i++) { diff --git a/test/main-override.c b/test/main-override.c index 836ea58d..ddb2f16e 100644 --- a/test/main-override.c +++ b/test/main-override.c @@ -3,30 +3,29 @@ #include #include -#include +//#include int main() { - mi_stats_reset(); + //mi_stats_reset(); void* p1 = malloc(78); void* p2 = malloc(24); free(p1); p1 = malloc(8); - char* s = strdup("hello\n"); + //char* s = strdup("hello\n"); free(p2); p2 = malloc(16); p1 = realloc(p1, 32); free(p1); free(p2); - free(s); - mi_collect(true); + //free(s); + //mi_collect(true); /* now test if override worked by allocating/freeing across the api's*/ - p1 = mi_malloc(32); - free(p1); - p2 = malloc(32); - mi_free(p2); + //p1 = mi_malloc(32); + //free(p1); + //p2 = malloc(32); + //mi_free(p2); - mi_stats_print(NULL); return 0; } diff --git a/test/main-override.cpp b/test/main-override.cpp index 3f2bc960..3c192fe3 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -22,15 +23,17 @@ public: ~Test() { } }; -int main() { - mi_stats_reset(); + +int main() { + //mi_malloc_override(); + mi_stats_reset(); atexit(free_p); void* p1 = malloc(78); - void* p2 = malloc(24); + void* p2 = _aligned_malloc(24,16); free(p1); p1 = malloc(8); - char* s = mi_strdup("hello\n"); - free(p2); + char* s = _strdup("hello\n"); + _aligned_free(p2); p2 = malloc(16); p1 = realloc(p1, 32); free(p1); @@ -40,12 +43,8 @@ int main() { delete t; t = new (std::nothrow) Test(42); delete t; - int err = mi_posix_memalign(&p1,32,60); - if (!err) free(p1); free(p); - mi_collect(true); - mi_stats_print(NULL); // MIMALLOC_VERBOSE env is set to 2 - return 0; + return 0; } class Static {