From ccbc8ae0bbfd71928dcb11b16ccad3c54c85e72d Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:46:28 -0800 Subject: [PATCH 01/23] add huge allocation test (see #544 by @Tiran) --- CMakeLists.txt | 2 +- test/test-api.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c05d09f..d32c630a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ if(MI_DEBUG_UBSAN) if(CMAKE_BUILD_TYPE MATCHES "Debug") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(STATUS "Build with undefined-behavior sanitizer (MI_DEBUG_UBSAN=ON)") - list(APPEND mi_cflags -fsanitize=undefined -g) + list(APPEND mi_cflags -fsanitize=undefined -g -fno-sanitize-recover=undefined) list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined) if (NOT MI_USE_CXX) message(STATUS "(switch to use C++ due to MI_DEBUG_UBSAN)") diff --git a/test/test-api.c b/test/test-api.c index 7ce6f111..0302464e 100644 --- a/test/test-api.c +++ b/test/test-api.c @@ -72,6 +72,10 @@ int main(void) { CHECK_BODY("calloc0",{ result = (mi_usable_size(mi_calloc(0,1000)) <= 16); }); + CHECK_BODY("malloc-large",{ // see PR #544. + void* p = mi_malloc(67108872); + mi_free(p); + }); // --------------------------------------------------- // Extended From 38639a08c8b75294fc18da05c7015eba88e2bbc5 Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:58:25 -0800 Subject: [PATCH 02/23] fix test-api-fill c++ compilation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d32c630a..d1207bb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,7 +175,7 @@ endif() if(MI_USE_CXX) message(STATUS "Use the C++ compiler to compile (MI_USE_CXX=ON)") set_source_files_properties(${mi_sources} PROPERTIES LANGUAGE CXX ) - set_source_files_properties(src/static.c test/test-api.c test/test-stress PROPERTIES LANGUAGE CXX ) + set_source_files_properties(src/static.c test/test-api.c test/test-api-fill test/test-stress PROPERTIES LANGUAGE CXX ) if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang") list(APPEND mi_cflags -Wno-deprecated) endif() From 8cf985ac8f4447b42df9d0475831073d8d3e549b Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 14 Feb 2022 15:44:50 -0800 Subject: [PATCH 03/23] fix warning on freebsd --- src/os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os.c b/src/os.c index 1939156c..757e8cab 100644 --- a/src/os.c +++ b/src/os.c @@ -311,7 +311,7 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats } } -#if !defined(MI_USE_SBRK) && !defined(__wasi__) +#if !(defined(__wasi__) || defined(MI_USE_SBRK) || defined(MAP_ALIGNED)) static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size); #endif @@ -662,7 +662,7 @@ static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) if (hint%try_alignment != 0) return NULL; return (void*)hint; } -#elif defined(__wasi__) || defined(MI_USE_SBRK) +#elif defined(__wasi__) || defined(MI_USE_SBRK) || defined(MAP_ALIGNED) // no need for mi_os_get_aligned_hint #else static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { From 8a1f8a305adb5708935a445ba2a5daf9961a4466 Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:14:51 -0800 Subject: [PATCH 04/23] prepare for x.0.4 release --- readme.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 635d983e..c59d1782 100644 --- a/readme.md +++ b/readme.md @@ -12,8 +12,8 @@ is a general purpose allocator with excellent [performance](#performance) charac Initially developed by Daan Leijen for the run-time systems of the [Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages. -Latest release tag: `v2.0.3` (beta, 2021-11-14). -Latest stable tag: `v1.7.3` (2021-11-14). +Latest release tag: `v2.0.4` (beta, 2022-02-14). +Latest stable tag: `v1.7.4` (2022-02-14). mimalloc is a drop-in replacement for `malloc` and can be used in other programs without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as: @@ -77,6 +77,12 @@ Note: the `v2.x` beta has a new algorithm for managing internal mimalloc pages t and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance (see [below](#performance)); please report if you observe any significant performance regression. +* 2022-02-14, `v1.7.4`, `v2.0.4` (alpha): fix malloc override on + Windows 11, fix compilation with musl, potentially reduced + committed memory, add `bin/minject` for Windows, + improved wasm support, faster aligned allocation, + various small fixes. + * 2021-11-14, `v1.7.3`, `v2.0.3` (beta): improved WASM support, improved macOS support and performance (including M1), improved performance for v2 for large objects, Python integration improvements, more standard installation directories, various small fixes. From c3b577df0d73af61fc5c6b84b1a61759b1fa84be Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:32:28 -0800 Subject: [PATCH 05/23] fix for macOS M1 Monteray to check pointers in zone_size --- src/alloc-override-osx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alloc-override-osx.c b/src/alloc-override-osx.c index a88186bc..9c331cae 100644 --- a/src/alloc-override-osx.c +++ b/src/alloc-override-osx.c @@ -43,7 +43,7 @@ extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_im static size_t zone_size(malloc_zone_t* zone, const void* p) { MI_UNUSED(zone); - //if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out + if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out return mi_usable_size(p); } From 817569dfad79732233fb86649c89e04387ce02e9 Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:34:18 -0800 Subject: [PATCH 06/23] bump to version x.0.5 --- cmake/mimalloc-config-version.cmake | 2 +- include/mimalloc.h | 2 +- readme.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/mimalloc-config-version.cmake b/cmake/mimalloc-config-version.cmake index 7bbd7313..c6a14a05 100644 --- a/cmake/mimalloc-config-version.cmake +++ b/cmake/mimalloc-config-version.cmake @@ -1,6 +1,6 @@ set(mi_version_major 1) set(mi_version_minor 7) -set(mi_version_patch 4) +set(mi_version_patch 5) set(mi_version ${mi_version_major}.${mi_version_minor}) set(PACKAGE_VERSION ${mi_version}) diff --git a/include/mimalloc.h b/include/mimalloc.h index 0b84f6c3..381f98c1 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -8,7 +8,7 @@ terms of the MIT license. A copy of the license can be found in the file #ifndef MIMALLOC_H #define MIMALLOC_H -#define MI_MALLOC_VERSION 174 // major + 2 digits minor +#define MI_MALLOC_VERSION 175 // major + 2 digits minor // ------------------------------------------------------ // Compiler specific attributes diff --git a/readme.md b/readme.md index c59d1782..2e5a2882 100644 --- a/readme.md +++ b/readme.md @@ -12,8 +12,8 @@ is a general purpose allocator with excellent [performance](#performance) charac Initially developed by Daan Leijen for the run-time systems of the [Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages. -Latest release tag: `v2.0.4` (beta, 2022-02-14). -Latest stable tag: `v1.7.4` (2022-02-14). +Latest release tag: `v2.0.5` (alpha, 2022-02-14). +Latest stable tag: `v1.7.5` (2022-02-14). mimalloc is a drop-in replacement for `malloc` and can be used in other programs without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as: @@ -77,7 +77,7 @@ Note: the `v2.x` beta has a new algorithm for managing internal mimalloc pages t and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance (see [below](#performance)); please report if you observe any significant performance regression. -* 2022-02-14, `v1.7.4`, `v2.0.4` (alpha): fix malloc override on +* 2022-02-14, `v1.7.5`, `v2.0.5` (alpha): fix malloc override on Windows 11, fix compilation with musl, potentially reduced committed memory, add `bin/minject` for Windows, improved wasm support, faster aligned allocation, From ec2265486ecf1d1868afa76c68bcbb8b70dd8fac Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:47:57 -0800 Subject: [PATCH 07/23] bump version for further development --- cmake/mimalloc-config-version.cmake | 2 +- include/mimalloc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/mimalloc-config-version.cmake b/cmake/mimalloc-config-version.cmake index c6a14a05..485c8e13 100644 --- a/cmake/mimalloc-config-version.cmake +++ b/cmake/mimalloc-config-version.cmake @@ -1,6 +1,6 @@ set(mi_version_major 1) set(mi_version_minor 7) -set(mi_version_patch 5) +set(mi_version_patch 6) set(mi_version ${mi_version_major}.${mi_version_minor}) set(PACKAGE_VERSION ${mi_version}) diff --git a/include/mimalloc.h b/include/mimalloc.h index 381f98c1..91ad352b 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -8,7 +8,7 @@ terms of the MIT license. A copy of the license can be found in the file #ifndef MIMALLOC_H #define MIMALLOC_H -#define MI_MALLOC_VERSION 175 // major + 2 digits minor +#define MI_MALLOC_VERSION 176 // major + 2 digits minor // ------------------------------------------------------ // Compiler specific attributes From 096b9015dc52f6dd35e923f1624e1862a1d1fa25 Mon Sep 17 00:00:00 2001 From: Christoph Erhardt Date: Tue, 22 Feb 2022 21:29:14 +0100 Subject: [PATCH 08/23] Fix compatibility with GNU libstdc++ < 9 So far, mimalloc does not override the `nothrow` variants of the `delete` operator because it assumes that their implementation in the C++ standard library redirects to the default `delete` operators. This is not the case for GNU libstdc++ < 9, where `std::free()` is called directly. This issue might be the cause for the crashes reported in #261. Upstream bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68210 This commit ensures that the `nothrow` `delete` operators are properly overridden by mimalloc. --- include/mimalloc-new-delete.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/mimalloc-new-delete.h b/include/mimalloc-new-delete.h index ba208f05..97149774 100644 --- a/include/mimalloc-new-delete.h +++ b/include/mimalloc-new-delete.h @@ -25,6 +25,9 @@ terms of the MIT license. A copy of the license can be found in the file void operator delete(void* p) noexcept { mi_free(p); }; void operator delete[](void* p) noexcept { mi_free(p); }; + void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); } + void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); } + void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } From db87d6a99cf347adf235301bcb150e47e05469a9 Mon Sep 17 00:00:00 2001 From: Daan Date: Tue, 22 Feb 2022 13:49:39 -0800 Subject: [PATCH 09/23] add delete nothrow variants for aligned deletion as well (see #551) --- include/mimalloc-new-delete.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/mimalloc-new-delete.h b/include/mimalloc-new-delete.h index 97149774..2749a0be 100644 --- a/include/mimalloc-new-delete.h +++ b/include/mimalloc-new-delete.h @@ -44,9 +44,11 @@ terms of the MIT license. A copy of the license can be found in the file void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; - - void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } - void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void operator delete (void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast(al)); } + + void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } #endif From 3040da1cb834f46077ac4bac3e44cff5878b74e9 Mon Sep 17 00:00:00 2001 From: Daan Date: Tue, 22 Feb 2022 13:52:31 -0800 Subject: [PATCH 10/23] add delete nothrow variants for aligned deletion as well (see #551) --- src/alloc-override.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/alloc-override.c b/src/alloc-override.c index 6bbe4aac..a3803c75 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -161,7 +161,9 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; - + void operator delete (void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& tag) noexcept { mi_free_aligned(p, static_cast(al)); } + void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } From 40e0507a5959ee218f308d33aec212c3ebeef3bb Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 21 Feb 2022 16:29:14 +0000 Subject: [PATCH 11/23] fix build on older macOs releases, aligned_alloc only from catalina. closes #549 --- src/alloc-override.c | 3 +++ src/random.c | 1 + 2 files changed, 4 insertions(+) diff --git a/src/alloc-override.c b/src/alloc-override.c index 6bbe4aac..fdd951b2 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -16,6 +16,7 @@ terms of the MIT license. A copy of the license can be found in the file #if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) #if defined(__APPLE__) +#include mi_decl_externc void vfree(void* p); mi_decl_externc size_t malloc_size(const void* p); mi_decl_externc size_t malloc_good_size(size_t size); @@ -77,7 +78,9 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; MI_INTERPOSE_MI(valloc), MI_INTERPOSE_MI(malloc_size), MI_INTERPOSE_MI(malloc_good_size), + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 MI_INTERPOSE_MI(aligned_alloc), + #endif #ifdef MI_OSX_ZONE // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely MI_INTERPOSE_MI(free), diff --git a/src/random.c b/src/random.c index 0b44c8b9..5057a623 100644 --- a/src/random.c +++ b/src/random.c @@ -195,6 +195,7 @@ static bool os_random_buf(void* buf, size_t buf_len) { #elif defined(__APPLE__) #include #if defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 +#include #include #endif static bool os_random_buf(void* buf, size_t buf_len) { From ccf117c43d11bce115c9672d50c370c7d35739a7 Mon Sep 17 00:00:00 2001 From: daan Date: Wed, 23 Feb 2022 10:04:25 -0800 Subject: [PATCH 12/23] update minject to use mimalloc.dll by default (issue #542) --- bin/minject.exe | Bin 20992 -> 20992 bytes bin/minject32.exe | Bin 17920 -> 18432 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/minject.exe b/bin/minject.exe index e5f87800d34eb1e04614a9e642eece2018b6cdf5..625816f1f7774c1f57b70033ea4fbb5e7a14e270 100644 GIT binary patch delta 8637 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 delta 8363 zcmeHMe^``NzJK2t21W#C1V&Ln1{?$h3BfgBz@34i-pQdQ#j-@B>yLD!;^It;t+$yP zXqnz-Z+dhew^i4N$GWvoyKj9|y;+)UC^$G^W72yu}OYS~gCXqidMV z%5+=#+^%CfUdJc0<5Bme?keOsK^zdmmOszrI4MPz<=1uSAzQYvTEiq>#~w12^VRGn zL(_!T0@$|oc*hH2fq%nJR=u+25q3+o<$-Oa6W=R7?-562%h$IkUc(FQ0ybBMg#NC`JgcR=o*fzY#ilpKKZPLl58kB(iK{FGQE?^abp6^e+;AhmO*g zYqC5jgyX}kC8o$+0+__ zSW3i15szi|2Ab9~TZuLek2tH>BVKchi#fm0 zcHFx}=--EY$SX`4t>}YZ@;+yvynypvf(X-an%3c~`t5TPA|CUoo{F z#>O-4)C+QNYme{vT(SO|(T$w99ryiC5MNVb!;+icGRc-N5bx_)SWX<0EyuvvhfMy~ zLyChK%oPrXg#O(Wi6HMr00{^{2<|q>mhwEB;z5ttzb)w1fjpwaI8hMIHF^DR z{ZZ*Jiv6>SH>vYG_VL(TN(UuBq#pED7E#2R!P2_(^lrW?1IT2-QxTdcPLc| zr{&U^FR}8tTz{2$g}qj{`mPl}oGQ0C*DB}_h|V;(z5lUjr@k-bOcR~Sqg=A+Oc~`; z++vm4iCq%hlWW=~=v?;QYu`k+#HtkWp*W}hT&QJjXk`oW!Inne^z=PQkV~v>sct*u zn~tc)dc;G+_2k7R9&l0lsct)NYMlc!57v@q-RAJ!FNVtW@l?{_Y7E_T-6zhv>E-WqW)&S*UL zkyCtMYP*CA?-F|;x&tD~M?4rGZa-a&uhW|oWK|G3sQ*T=+ggyA8t9aEE5);?9-_%-; ztG@UU-G8;NaFtHBe24CeTDII8v8*ocfz47$wtSq$niHqYIGRcO2R_2{dF9weqn5~) zlhoI~&(wAr(P&Oy$zppFpR||K)KMDR+9=NXMsYYi7Z>Iv#nH)<^v@j}=QEb1e+u+g z3*r$>?i-q1&j@=WX=2(nT9(7o))6g(pEQ2~iwk7&4C_h~_%-Zm($81;5P@Wc(V#dW zTW+^f7)N1P0XeP?$v`Sq^iwkZ=5NG@<2Mo`X^ce7agBK!5lZiB%vRFu{u}!wc{V?W zC0lOMotn(5Etz@I8RUPTK;?8mpxdpE#tzSw`=au=>+hvxw$4(R+&+gRwc#{UY`O>g zyW-3gcEpn7uboU4)OUY%>m{$F#NdFPZ=OfQt0Vr8%5of)(!ava-Y;7gV9Ym=F8J}- zYB4+6G94n*PM57V|K68QcqauazOPX9@w=(7srpmw!ZY7MBwOCYKq%dViqp6IAtNbf zwRXJKZ-gJW{dS|N?IOg2_>OGZNA^U#20{(!BQ2oj^RgVMSVKeMrGf82#lyt-=1@Mu z@nk2}z=)!5L-(7az7L|&sK?-e6)&O7aIp}sQ!Y!{Vog`lGDdj`rh-v2jf+c8k&T_!ZVhkqtmpt zulSNXDD$RY9>Y0N%Bm+kBLH3G?co;Ft_JKgeCEK<`Nw>*fuHM;*oaV}3!XpY z)*MWOgEhWHa^Q>WGyFnP=3nQ%QS+XS=SbLc42fb#QzjQzDTZfh-L;TcMMB;OAxyWx zltNwuSPAxGFPnZ8;byAeCM4z`Qd+ecI#9px2sNMOBR+KMhmIcovKIfVk%5+^pJ<8aX1IjnOgrsEUvh=7yU$u7lzG!h9zal!*EQW zVLlPcn_D(LYsVvoj$r~;+z;o{^s}-&e4Fx=3!!tMA{*wMHx`>xdh0TD(_vYi3CqG^ zlqnHEch2KUCB7qB!Q+79^pWjT%8SZhZ>ueasFCWj*Vcf_Z~fsar1RcLo+e;S6s*JG zKOjD4l;2GJb~Voty6fc z#eUx%{e~|g0z=E)Fo_`E36S#P84t_YZW+2W$5ew1)xbyw1{m}kUS@mK9Q<}>NY5-8 zG(x-%U$~#8-z%6R{TAqDJLHDJ&5W2?5EN-{4hhfx%ly7 z!xUnnm3{$d*l%X=iNya*;k^Y#J;TK-OphA=BL$%b2jmMTzv0-AK!*&U0f;38I}GSE z{1M-LCr|6VsP}cm&PhwyiOI={6-Q***CH&9Zvuh*%{amg8S9chn?-)fSY6RT#ZmTh zMt=IMkYjfp^TkNB5$>=_-5#4EmNMAa8FSpZ)bq`vjuSI}O~0D#y*{rHT%LkOsY#J7 zWyz3<)hR-#+ALeHCSm?P!c3wil@8ZfRsJAbV=eQ)P)zpqHbJ^MihX#D;mV=F4C0NZZ};%^$1O;;#B z0Mhivm&vB!I#uux1aD%oxlsBtcFZKFrr;v)WFUpY+8CRjz8%W9&P?*{3O!Y!+ZFm%}H(rdjU*`R#?s#1YX z%C|ajltSO8m~K<(4&_@N;6;TFBv2^L%6A=`In~J*b*-Kn=9yVv=s&O+Il#xdM8z*O z{`-2BPto`S4R>nTp<%m*UJaLM=+ZDs^Q(G8k<$1|75&`Rg{ms~UKOWn__ZdNG!!&> z#8K>hT0ae6xkAg4UpHcL5%W0oyG{XqLQsb{`Xw)2bYy4IX=V@4`=>-kv zX;`n}cnz0nfqX>$X#5^c@v(+iG>q1k;Bjq$*&60+`beNVHHU{ZoUG|}ntg{R-=yKw z8a@G3=6{D~*r+KSk%2VqylKEJO@2wUKd0ej=TVmD#vkMf68B`XL7M6(f;tNhaYHce01rI zM;}|>+`MYpa+XnOXB~yRC*=H-s$f}TV@}uVng7YN4aL9tmj*wc^`wsdX?ERW`ZF^P zhx*6OM@y+iDr3-_p3Nv-bgwy!K~tw_PC|zA zr^QvLco-oW@?FqOvx2ggy<0ZHkHnAYB2wGqk3YWb-!MJSh}BeP*6dwsb1M_$%s0sH zQ@o~JFRN4StT)J1yIjbgrEyx+(O+A@aj#*VQZ30?0wnov>>i*dD<)Y0vg;NDuM|94 z7IIt*+hQLY2d|kBG~vSDfVOZxd%8R)B0UL-jMhG%y;VMEPR}Hc`)exB3w1K;IOE=A zh3E11zou6l$=OPZAo zz`voclX)TQhOBe6Zx#1EgoTw@$?FXN1ep;ITdtFR4A~WQrcD$1%%Xzp!2h-W|5}fv zg!?~vtt%Jr|K7FE&N`oG&sCOmeNeee$9`XZ8xyOux-L}5>$-ZT=JKx!V|0F0nFiG5 z7tl&TcLEJ4P%hAB;G<}@phwG@TGl>*ya95;kI-5`j}|wz$PFgK7IMPR(Kj&p_jb`kg!)Veg#g!O3ops%lSR12%E_@M(i;VHD0 zpb7tu)()C5E|cRn*WqDB#B8)zpdhS5qYi|%nw;=%8)_=#4Zxfn%oa4>JKU#eG#k8m zI6Q>7tB@1YzqW~v1Gb~aMd5lOd>)PDn}J8Bp^yyF$VojV409NaOqX5o>Mpg diff --git a/bin/minject32.exe b/bin/minject32.exe index d0181028259e768db2eb6a706c2ed6d4ecba34ee..6857ad0ce1ccd014ed02c99d2c13feb5783fddb9 100644 GIT binary patch delta 6984 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 Ov?E%Qf^Wp_%zp#Ta=ym^ delta 6598 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 Date: Sat, 2 Apr 2022 09:29:09 -0700 Subject: [PATCH 13/23] add thread id to trace, warning, and error messages --- src/options.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/options.c b/src/options.c index c4ed91cb..4a433353 100644 --- a/src/options.c +++ b/src/options.c @@ -322,11 +322,22 @@ void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) { va_end(args); } +static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) { + if (prefix != NULL && strlen(prefix) <= 32 && !_mi_is_main_thread()) { + char tprefix[64]; + snprintf(tprefix, sizeof(tprefix), "%sthread 0x%zx: ", prefix, _mi_thread_id()); + mi_vfprintf(out, arg, tprefix, fmt, args); + } + else { + mi_vfprintf(out, arg, prefix, fmt, args); + } +} + void _mi_trace_message(const char* fmt, ...) { if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher va_list args; va_start(args, fmt); - mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); + mi_vfprintf_thread(NULL, NULL, "mimalloc: ", fmt, args); va_end(args); } @@ -341,7 +352,7 @@ void _mi_verbose_message(const char* fmt, ...) { static void mi_show_error_message(const char* fmt, va_list args) { if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; if (mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; - mi_vfprintf(NULL, NULL, "mimalloc: error: ", fmt, args); + mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args); } void _mi_warning_message(const char* fmt, ...) { @@ -349,7 +360,7 @@ void _mi_warning_message(const char* fmt, ...) { if (mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; va_list args; va_start(args,fmt); - mi_vfprintf(NULL, NULL, "mimalloc: warning: ", fmt, args); + mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args); va_end(args); } From b2598e7ee44899cdef53c772698ddeed92c5aea5 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Sat, 2 Apr 2022 09:46:25 -0700 Subject: [PATCH 14/23] allow setting MIMALLOC_MAX_ERRORS/WARNINGS to -1 to get unlimited error/warning messages --- src/options.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/options.c b/src/options.c index 4a433353..5c388ea2 100644 --- a/src/options.c +++ b/src/options.c @@ -19,8 +19,8 @@ terms of the MIT license. A copy of the license can be found in the file #endif -static size_t mi_max_error_count = 16; // stop outputting errors after this -static size_t mi_max_warning_count = 16; // stop outputting warnings after this +static long mi_max_error_count = 16; // stop outputting errors after this (use < 0 for no limit) +static long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit) static void mi_add_stderr_output(void); @@ -351,13 +351,13 @@ void _mi_verbose_message(const char* fmt, ...) { static void mi_show_error_message(const char* fmt, va_list args) { if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; - if (mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; + if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args); } void _mi_warning_message(const char* fmt, ...) { if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; - if (mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; + if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; va_list args; va_start(args,fmt); mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args); From 3fa53244c29048fd3b934be7505b4b73475dc6eb Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Sat, 2 Apr 2022 10:11:36 -0700 Subject: [PATCH 15/23] add better warning messages if aligning or freeing OS memory fails --- src/os.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/os.c b/src/os.c index 757e8cab..288cbae4 100644 --- a/src/os.c +++ b/src/os.c @@ -295,20 +295,20 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats bool err = false; #if defined(_WIN32) err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); + if (err) { + _mi_warning_message("unable to release OS memory: error code 0x%x, addr: %p, size: %zu\n", GetLastError(), addr, size); + } #elif defined(MI_USE_SBRK) || defined(__wasi__) - err = 0; // sbrk heap cannot be shrunk + err = false; // sbrk heap cannot be shrunk #else err = (munmap(addr, size) == -1); -#endif - if (was_committed) _mi_stat_decrease(&stats->committed, size); - _mi_stat_decrease(&stats->reserved, size); if (err) { - _mi_warning_message("munmap failed: %s, addr 0x%8li, size %lu\n", strerror(errno), (size_t)addr, size); - return false; - } - else { - return true; + _mi_warning_message("unable to release OS memory: %s, addr: %p, size: %zu\n", strerror(errno), addr, size); } +#endif + if (was_committed) { _mi_stat_decrease(&stats->committed, size); } + _mi_stat_decrease(&stats->reserved, size); + return !err; } #if !(defined(__wasi__) || defined(MI_USE_SBRK) || defined(MAP_ALIGNED)) @@ -336,7 +336,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment return NULL; } */ - _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: %x, address: %p, alignment: %d, flags: %x)\n", size, GetLastError(), hint, try_alignment, flags); + _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); } } #endif @@ -350,7 +350,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment param.Pointer = &reqs; void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); if (p != NULL) return p; - _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: %x, address: %p, alignment: %d, flags: %x)\n", size, GetLastError(), addr, try_alignment, flags); + _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags); // fall through on error } #endif @@ -362,6 +362,7 @@ static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, mi_assert_internal(!(large_only && !allow_large)); static _Atomic(size_t) large_page_try_ok; // = 0; void* p = NULL; + // Try to allocate large OS pages (2MiB) if allowed or required. if ((large_only || use_large_os_page(size, try_alignment)) && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); @@ -381,12 +382,13 @@ static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, } } } + // Fall back to regular page allocation if (p == NULL) { *is_large = ((flags&MEM_LARGE_PAGES) != 0); p = mi_win_virtual_allocx(addr, size, try_alignment, flags); } if (p == NULL) { - _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, GetLastError(), addr, large_only, allow_large); + _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); } return p; } @@ -695,7 +697,7 @@ static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, boo #if defined(_WIN32) int flags = MEM_RESERVE; - if (commit) flags |= MEM_COMMIT; + if (commit) { flags |= MEM_COMMIT; } p = mi_win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); #elif defined(MI_USE_SBRK) || defined(__wasi__) MI_UNUSED(allow_large); @@ -729,9 +731,10 @@ static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, // if not aligned, free it, overallocate, and unmap around it if (((uintptr_t)p % alignment != 0)) { + _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, commit: %d, is_large: %d)\n", size, p, commit, *is_large); mi_os_mem_free(p, size, commit, stats); if (size >= (SIZE_MAX - alignment)) return NULL; // overflow - size_t over_size = size + alignment; + const size_t over_size = size + alignment; #if _WIN32 // over-allocate and than re-allocate exactly at an aligned address in there. From d1db0ffb72d9e89e3d3c31b9115129c91dc7ced5 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Sat, 2 Apr 2022 11:26:56 -0700 Subject: [PATCH 16/23] when MIMALLOC_VERBOSE is set, the all errors/warnings are shown --- src/options.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/options.c b/src/options.c index 5c388ea2..2022d964 100644 --- a/src/options.c +++ b/src/options.c @@ -350,14 +350,18 @@ void _mi_verbose_message(const char* fmt, ...) { } static void mi_show_error_message(const char* fmt, va_list args) { - if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; - if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; + } mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args); } void _mi_warning_message(const char* fmt, ...) { - if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; - if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; + } va_list args; va_start(args,fmt); mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args); From 72ab945e285e41427222ef4c3cc82ac1ba5ffb84 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Sat, 2 Apr 2022 11:38:07 -0700 Subject: [PATCH 17/23] improve fallback code for aligned allocation on Windows --- src/os.c | 68 ++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/os.c b/src/os.c index 288cbae4..bedf44cf 100644 --- a/src/os.c +++ b/src/os.c @@ -67,7 +67,8 @@ terms of the MIT license. A copy of the license can be found in the file On windows initializes support for aligned allocation and large OS pages (if MIMALLOC_LARGE_OS_PAGES is true). ----------------------------------------------------------- */ -bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats); static void* mi_align_up_ptr(void* p, size_t alignment) { return (void*)_mi_align_up((uintptr_t)p, alignment); @@ -294,9 +295,23 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats if (addr == NULL || size == 0) return true; // || _mi_os_is_huge_reserved(addr) bool err = false; #if defined(_WIN32) + DWORD errcode = 0; err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); - if (err) { - _mi_warning_message("unable to release OS memory: error code 0x%x, addr: %p, size: %zu\n", GetLastError(), addr, size); + if (err) { errcode = GetLastError(); } + if (errcode == ERROR_INVALID_ADDRESS) { + // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside + // the memory region returned by VirtualAlloc; in that case we need to free using + // the start of the region. + MEMORY_BASIC_INFORMATION info = { 0, 0 }; + VirtualQuery(addr, &info, sizeof(info)); + if (info.AllocationBase < addr) { + errcode = 0; + err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0); + if (err) { errcode = GetLastError(); } + } + } + if (errcode != 0) { + _mi_warning_message("unable to release OS memory: error code 0x%x, addr: %p, size: %zu\n", errcode, addr, size); } #elif defined(MI_USE_SBRK) || defined(__wasi__) err = false; // sbrk heap cannot be shrunk @@ -728,46 +743,27 @@ static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, // try first with a hint (this will be aligned directly on Win 10+ or BSD) void* p = mi_os_mem_alloc(size, alignment, commit, allow_large, is_large, stats); if (p == NULL) return NULL; - + // if not aligned, free it, overallocate, and unmap around it if (((uintptr_t)p % alignment != 0)) { - _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, commit: %d, is_large: %d)\n", size, p, commit, *is_large); mi_os_mem_free(p, size, commit, stats); + _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, commit: %d, is_large: %d)\n", size, p, commit, *is_large); if (size >= (SIZE_MAX - alignment)) return NULL; // overflow const size_t over_size = size + alignment; #if _WIN32 - // over-allocate and than re-allocate exactly at an aligned address in there. - // this may fail due to threads allocating at the same time so we - // retry this at most 3 times before giving up. - // (we can not decommit around the overallocation on Windows, because we can only - // free the original pointer, not one pointing inside the area) - int flags = MEM_RESERVE; - if (commit) flags |= MEM_COMMIT; - for (int tries = 0; tries < 3; tries++) { - // over-allocate to determine a virtual memory range - p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats); - if (p == NULL) return NULL; // error - if (((uintptr_t)p % alignment) == 0) { - // if p happens to be aligned, just decommit the left-over area - _mi_os_decommit((uint8_t*)p + size, over_size - size, stats); - break; - } - else { - // otherwise free and allocate at an aligned address in there - mi_os_mem_free(p, over_size, commit, stats); - void* aligned_p = mi_align_up_ptr(p, alignment); - p = mi_win_virtual_alloc(aligned_p, size, alignment, flags, false, allow_large, is_large); - if (p != NULL) { - _mi_stat_increase(&stats->reserved, size); - if (commit) { _mi_stat_increase(&stats->committed, size); } - } - if (p == aligned_p) break; // success! - if (p != NULL) { // should not happen? - mi_os_mem_free(p, size, commit, stats); - p = NULL; - } - } + // over-allocate uncommitted (virtual) memory + p = mi_os_mem_alloc(over_size, 0 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, stats); + if (p == NULL) return NULL; + + // set p to the aligned part in the full region + // note: this is dangerous on Windows as VirtualFree needs the actual region pointer + // but in mi_os_mem_free we handle this (hopefully exceptional) situation. + p = mi_align_up_ptr(p, alignment); + + // explicitly commit only the aligned part + if (commit) { + _mi_os_commit(p, size, NULL, stats); } #else // overallocate... From 5613ffb50834bc1e796f96e7d95b11d238dae491 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Mon, 4 Apr 2022 17:38:28 -0700 Subject: [PATCH 18/23] use heap_stat_increase macros when possible --- src/page.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/page.c b/src/page.c index 6efeba2a..386898fa 100644 --- a/src/page.c +++ b/src/page.c @@ -252,7 +252,7 @@ static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size // a fresh page was found, initialize it mi_assert_internal(pq==NULL || _mi_page_segment(page)->page_kind != MI_PAGE_HUGE); mi_page_init(heap, page, block_size, heap->tld); - _mi_stat_increase(&heap->tld->stats.pages, 1); + mi_heap_stat_increase(heap, pages, 1); if (pq!=NULL) mi_page_queue_push(heap, pq, page); // huge pages use pq==NULL mi_assert_expensive(_mi_page_is_valid(page)); return page; @@ -688,7 +688,7 @@ static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* p page = next; } // for each page - mi_stat_counter_increase(heap->tld->stats.searches, count); + mi_heap_stat_counter_increase(heap, searches, count); if (page == NULL) { _mi_heap_collect_retired(heap, false); // perhaps make a page available @@ -780,12 +780,12 @@ static mi_page_t* mi_huge_page_alloc(mi_heap_t* heap, size_t size) { mi_page_set_heap(page, NULL); if (bsize > MI_HUGE_OBJ_SIZE_MAX) { - _mi_stat_increase(&heap->tld->stats.giant, bsize); - _mi_stat_counter_increase(&heap->tld->stats.giant_count, 1); + mi_heap_stat_increase(heap, giant, bsize); + mi_heap_stat_counter_increase(heap, giant_count, 1); } else { - _mi_stat_increase(&heap->tld->stats.huge, bsize); - _mi_stat_counter_increase(&heap->tld->stats.huge_count, 1); + mi_heap_stat_increase(heap, huge, bsize); + mi_heap_stat_counter_increase(heap, huge_count, 1); } } return page; From 049d37c349a349a576654a717d237c6e45991e3a Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 10:19:26 -0700 Subject: [PATCH 19/23] fix formatting flags for warning messages --- src/os.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/os.c b/src/os.c index bedf44cf..281d83b5 100644 --- a/src/os.c +++ b/src/os.c @@ -341,7 +341,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment if (addr == NULL) { void* hint = mi_os_get_aligned_hint(try_alignment,size); if (hint != NULL) { - void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); + void* p = NULL; // VirtualAlloc(hint, size, flags, PAGE_READWRITE); if (p != NULL) return p; // for robustness always fall through in case of an error /* @@ -351,7 +351,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment return NULL; } */ - _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); + _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); } } #endif @@ -365,7 +365,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment param.Pointer = &reqs; void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); if (p != NULL) return p; - _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags); + _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags); // fall through on error } #endif @@ -403,7 +403,7 @@ static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, p = mi_win_virtual_allocx(addr, size, try_alignment, flags); } if (p == NULL) { - _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %d, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); + _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); } return p; } @@ -736,6 +736,7 @@ static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, boo static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) { mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0)); mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(is_large != NULL); if (!commit) allow_large = false; if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL; size = _mi_align_up(size, _mi_os_page_size()); @@ -747,7 +748,7 @@ static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, // if not aligned, free it, overallocate, and unmap around it if (((uintptr_t)p % alignment != 0)) { mi_os_mem_free(p, size, commit, stats); - _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, commit: %d, is_large: %d)\n", size, p, commit, *is_large); + _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (%zu bytes, address: %p, alignment: %zu, commit: %d)\n", size, p, alignment, commit); if (size >= (SIZE_MAX - alignment)) return NULL; // overflow const size_t over_size = size + alignment; From 58af58d084d57e43690ae78d0b8dad4303090096 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 10:21:49 -0700 Subject: [PATCH 20/23] fix debug edit --- src/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os.c b/src/os.c index 281d83b5..62c98dae 100644 --- a/src/os.c +++ b/src/os.c @@ -341,7 +341,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment if (addr == NULL) { void* hint = mi_os_get_aligned_hint(try_alignment,size); if (hint != NULL) { - void* p = NULL; // VirtualAlloc(hint, size, flags, PAGE_READWRITE); + void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); if (p != NULL) return p; // for robustness always fall through in case of an error /* From a799b214a2429908cbfcb6e083b1606869c96696 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 12:33:25 -0700 Subject: [PATCH 21/23] fix issue with log messages sometimes failing on Windows if the console cannot be locked; use direct console output now --- src/options.c | 14 +++++++++++++- src/os.c | 9 +-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/options.c b/src/options.c index 2022d964..e1944a19 100644 --- a/src/options.c +++ b/src/options.c @@ -163,10 +163,22 @@ void mi_option_disable(mi_option_t option) { static void mi_out_stderr(const char* msg, void* arg) { MI_UNUSED(arg); + if (msg == NULL) return; #ifdef _WIN32 // on windows with redirection, the C runtime cannot handle locale dependent output // after the main thread closes so we use direct console output. - if (!_mi_preloading()) { _cputs(msg); } + if (!_mi_preloading()) { + // _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console + static HANDLE hcon = INVALID_HANDLE_VALUE; + if (hcon == INVALID_HANDLE_VALUE) { + hcon = GetStdHandle(STD_ERROR_HANDLE); + } + const size_t len = strlen(msg); + if (hcon != INVALID_HANDLE_VALUE && len > 0 && len < UINT32_MAX) { + DWORD written = 0; + WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL); + } + } #else fputs(msg, stderr); #endif diff --git a/src/os.c b/src/os.c index 62c98dae..52939faa 100644 --- a/src/os.c +++ b/src/os.c @@ -343,15 +343,8 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment if (hint != NULL) { void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); if (p != NULL) return p; - // for robustness always fall through in case of an error - /* - DWORD err = GetLastError(); - if (err != ERROR_INVALID_ADDRESS && // If linked with multiple instances, we may have tried to allocate at an already allocated area (#210) - err != ERROR_INVALID_PARAMETER) { // Windows7 instability (#230) - return NULL; - } - */ _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); + // fall through on error } } #endif From 82dd094ec4d7f36067fdd55aa10aea438dae588f Mon Sep 17 00:00:00 2001 From: Daan Date: Thu, 7 Apr 2022 13:02:40 -0700 Subject: [PATCH 22/23] fix assertion failure with mixed pointer errors --- src/alloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/alloc.c b/src/alloc.c index cd4afa1e..5f150f24 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -470,6 +470,7 @@ static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* ms #if (MI_DEBUG>0 || MI_SECURE>=4) if (mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) { _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p); + return NULL; } #endif return segment; From 25ecec3c3b77a85f1344bacb6c9538c555b49e12 Mon Sep 17 00:00:00 2001 From: Daan Date: Thu, 7 Apr 2022 16:12:16 -0700 Subject: [PATCH 23/23] fix for dynamic overriding on macOS; add warning about C++ compilation (as that does not interact well with interpose) --- CMakeLists.txt | 4 ++-- src/alloc-override-osx.c | 4 ++-- src/alloc-override.c | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1207bb1..b7023009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,8 +97,8 @@ if(MI_OVERRIDE) message(STATUS " WARNING: interpose usually also needs zone overriding (use -DMI_OSX_INTERPOSE=ON)") endif() endif() - if((NOT MI_USE_CXX) AND MI_OVERRIDE) - message(STATUS " WARNING: if overriding C++ new/delete, it is best to build mimalloc with a C++ compiler (use -DMI_USE_CXX=ON)") + if(MI_USE_CXX AND MI_OSX_INTERPOSE) + message(STATUS " WARNING: if dynamically overriding malloc/free, it is more reliable to build mimalloc as C code (use -DMI_USE_CXX=OFF)") endif() endif() endif() diff --git a/src/alloc-override-osx.c b/src/alloc-override-osx.c index 9c331cae..41d0a386 100644 --- a/src/alloc-override-osx.c +++ b/src/alloc-override-osx.c @@ -64,7 +64,7 @@ static void* zone_valloc(malloc_zone_t* zone, size_t size) { static void zone_free(malloc_zone_t* zone, void* p) { MI_UNUSED(zone); - mi_free(p); + mi_cfree(p); } static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { @@ -373,7 +373,7 @@ __attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[] MI_INTERPOSE_MI(_malloc_fork_child), MI_INTERPOSE_MI(_malloc_fork_parent), MI_INTERPOSE_MI(_malloc_fork_prepare), - + MI_INTERPOSE_ZONE(zone_batch_free), MI_INTERPOSE_ZONE(zone_batch_malloc), MI_INTERPOSE_ZONE(zone_calloc), diff --git a/src/alloc-override.c b/src/alloc-override.c index 0c9ece91..12e9e0d6 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -94,15 +94,18 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; #ifdef __cplusplus extern "C" { - void _ZdlPv(void* p); // delete - void _ZdaPv(void* p); // delete[] - void _ZdlPvm(void* p, size_t n); // delete - void _ZdaPvm(void* p, size_t n); // delete[] - void* _Znwm(size_t n); // new - void* _Znam(size_t n); // new[] - void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow - void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow - } + #endif + void _ZdlPv(void* p); // delete + void _ZdaPv(void* p); // delete[] + void _ZdlPvm(void* p, size_t n); // delete + void _ZdaPvm(void* p, size_t n); // delete[] + void* _Znwm(size_t n); // new + void* _Znam(size_t n); // new[] + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow + #ifdef __cplusplus + } + #endif __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[] __attribute__((section("__DATA, __interpose"))) = { MI_INTERPOSE_FUN(_ZdlPv,mi_free), @@ -114,7 +117,6 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow), MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow), }; - #endif // __cplusplus #elif defined(_MSC_VER) // cannot override malloc unless using a dll.