From e87b1d2298313f2ec47da0d76dbfc195742126fc Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:08:13 -0800 Subject: [PATCH 01/29] add extra huge allocation test --- test/main-override-static.c | 351 +++++++++++++++++++----------------- 1 file changed, 182 insertions(+), 169 deletions(-) diff --git a/test/main-override-static.c b/test/main-override-static.c index afb9131e..07116503 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -8,172 +8,6 @@ #include // redefines malloc etc. -#include -#include - -#define MI_INTPTR_SIZE 8 -#define MI_LARGE_WSIZE_MAX (4*1024*1024 / MI_INTPTR_SIZE) - -#define MI_BIN_HUGE 100 -//#define MI_ALIGN2W - -// Bit scan reverse: return the index of the highest bit. -static inline uint8_t mi_bsr32(uint32_t x); - -#if defined(_MSC_VER) -#include -#include -static inline uint8_t mi_bsr32(uint32_t x) { - uint32_t idx; - _BitScanReverse((DWORD*)&idx, x); - return idx; -} -#elif defined(__GNUC__) || defined(__clang__) -static inline uint8_t mi_bsr32(uint32_t x) { - return (31 - __builtin_clz(x)); -} -#else -static inline uint8_t mi_bsr32(uint32_t x) { - // de Bruijn multiplication, see - static const uint8_t debruijn[32] = { - 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12, - 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13, - }; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x++; - return debruijn[(x*0x076be629) >> 27]; -} -#endif - -/* -// Bit scan reverse: return the index of the highest bit. -uint8_t _mi_bsr(uintptr_t x) { - if (x == 0) return 0; - #if MI_INTPTR_SIZE==8 - uint32_t hi = (x >> 32); - return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); - #elif MI_INTPTR_SIZE==4 - return mi_bsr32(x); - #else - # error "define bsr for non-32 or 64-bit platforms" - #endif -} -*/ - - -static inline size_t _mi_wsize_from_size(size_t size) { - return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); -} - -// Return the bin for a given field size. -// Returns MI_BIN_HUGE if the size is too large. -// We use `wsize` for the size in "machine word sizes", -// i.e. byte size == `wsize*sizeof(void*)`. -extern inline uint8_t _mi_bin8(size_t size) { - size_t wsize = _mi_wsize_from_size(size); - uint8_t bin; - if (wsize <= 1) { - bin = 1; - } - #if defined(MI_ALIGN4W) - else if (wsize <= 4) { - bin = (uint8_t)((wsize+1)&~1); // round to double word sizes - } - #elif defined(MI_ALIGN2W) - else if (wsize <= 8) { - bin = (uint8_t)((wsize+1)&~1); // round to double word sizes - } - #else - else if (wsize <= 8) { - bin = (uint8_t)wsize; - } - #endif - else if (wsize > MI_LARGE_WSIZE_MAX) { - bin = MI_BIN_HUGE; - } - else { - #if defined(MI_ALIGN4W) - if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes - #endif - wsize--; - // find the highest bit - uint8_t b = mi_bsr32((uint32_t)wsize); - // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). - // - adjust with 3 because we use do not round the first 8 sizes - // which each get an exact bin - bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; - } - return bin; -} - -extern inline uint8_t _mi_bin4(size_t size) { - size_t wsize = _mi_wsize_from_size(size); - uint8_t bin; - if (wsize <= 1) { - bin = 1; - } - #if defined(MI_ALIGN4W) - else if (wsize <= 4) { - bin = (uint8_t)((wsize+1)&~1); // round to double word sizes - } - #elif defined(MI_ALIGN2W) - else if (wsize <= 8) { - bin = (uint8_t)((wsize+1)&~1); // round to double word sizes - } - #else - else if (wsize <= 8) { - bin = (uint8_t)wsize; - } - #endif - else if (wsize > MI_LARGE_WSIZE_MAX) { - bin = MI_BIN_HUGE; - } - else { - uint8_t b = mi_bsr32((uint32_t)wsize); - bin = ((b << 1) + (uint8_t)((wsize >> (b - 1)) & 0x01)) + 3; - } - return bin; -} - -size_t _mi_binx4(size_t bsize) { - if (bsize==0) return 0; - uint8_t b = mi_bsr32((uint32_t)bsize); - if (b <= 1) return bsize; - size_t bin = ((b << 1) | (bsize >> (b - 1))&0x01); - return bin; -} - -size_t _mi_binx8(size_t bsize) { - if (bsize<=1) return bsize; - uint8_t b = mi_bsr32((uint32_t)bsize); - if (b <= 2) return bsize; - size_t bin = ((b << 2) | (bsize >> (b - 2))&0x03) - 5; - return bin; -} - -void mi_bins() { - //printf(" QNULL(1), /* 0 */ \\\n "); - size_t last_bin = 0; - size_t min_bsize = 0; - size_t last_bsize = 0; - for (size_t bsize = 1; bsize < 2*1024; bsize++) { - size_t size = bsize * 64 * 1024; - size_t bin = _mi_binx8(bsize); - if (bin != last_bin) { - printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_bsize, last_bsize, last_bin); - //printf("QNULL(%6zd), ", wsize); - //if (last_bin%8 == 0) printf("/* %i */ \\\n ", last_bin); - last_bin = bin; - min_bsize = bsize; - } - last_bsize = bsize; - } -} - static void double_free1(); static void double_free2(); static void corrupt_free(); @@ -183,7 +17,7 @@ static void test_aslr(void); static void test_process_info(void); static void test_reserved(void); static void negative_stat(void); - +static void alloc_huge(void); int main() { mi_version(); @@ -197,6 +31,7 @@ int main() { // invalid_free(); // test_reserved(); // negative_stat(); + alloc_huge(); void* p1 = malloc(78); void* p2 = malloc(24); @@ -210,7 +45,7 @@ int main() { free(p1); free(p2); free(s); - + /* now test if override worked by allocating/freeing across the api's*/ //p1 = mi_malloc(32); //free(p1); @@ -347,4 +182,182 @@ static void negative_stat(void) { *p = 100; mi_free(p); mi_stats_print_out(NULL, NULL); -} \ No newline at end of file +} + +static void alloc_huge(void) { + void* p = mi_malloc(67108872); + mi_free(p); +} + + +// ---------------------------- +// bin size experiments +// ------------------------------ + +#if 0 +#include +#include + +#define MI_INTPTR_SIZE 8 +#define MI_LARGE_WSIZE_MAX (4*1024*1024 / MI_INTPTR_SIZE) + +#define MI_BIN_HUGE 100 +//#define MI_ALIGN2W + +// Bit scan reverse: return the index of the highest bit. +static inline uint8_t mi_bsr32(uint32_t x); + +#if defined(_MSC_VER) +#include +#include +static inline uint8_t mi_bsr32(uint32_t x) { + uint32_t idx; + _BitScanReverse((DWORD*)&idx, x); + return idx; +} +#elif defined(__GNUC__) || defined(__clang__) +static inline uint8_t mi_bsr32(uint32_t x) { + return (31 - __builtin_clz(x)); +} +#else +static inline uint8_t mi_bsr32(uint32_t x) { + // de Bruijn multiplication, see + static const uint8_t debruijn[32] = { + 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12, + 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13, + }; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return debruijn[(x*0x076be629) >> 27]; +} +#endif + +/* +// Bit scan reverse: return the index of the highest bit. +uint8_t _mi_bsr(uintptr_t x) { + if (x == 0) return 0; + #if MI_INTPTR_SIZE==8 + uint32_t hi = (x >> 32); + return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); + #elif MI_INTPTR_SIZE==4 + return mi_bsr32(x); + #else + # error "define bsr for non-32 or 64-bit platforms" + #endif +} +*/ + + +static inline size_t _mi_wsize_from_size(size_t size) { + return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +// Return the bin for a given field size. +// Returns MI_BIN_HUGE if the size is too large. +// We use `wsize` for the size in "machine word sizes", +// i.e. byte size == `wsize*sizeof(void*)`. +extern inline uint8_t _mi_bin8(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } +#if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } +#endif + else if (wsize > MI_LARGE_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { +#if defined(MI_ALIGN4W) + if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes +#endif + wsize--; + // find the highest bit + uint8_t b = mi_bsr32((uint32_t)wsize); + // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). + // - adjust with 3 because we use do not round the first 8 sizes + // which each get an exact bin + bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; + } + return bin; +} + +static inline uint8_t _mi_bin4(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } +#if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } +#else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } +#endif + else if (wsize > MI_LARGE_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { + uint8_t b = mi_bsr32((uint32_t)wsize); + bin = ((b << 1) + (uint8_t)((wsize >> (b - 1)) & 0x01)) + 3; + } + return bin; +} + +static size_t _mi_binx4(size_t bsize) { + if (bsize==0) return 0; + uint8_t b = mi_bsr32((uint32_t)bsize); + if (b <= 1) return bsize; + size_t bin = ((b << 1) | (bsize >> (b - 1))&0x01); + return bin; +} + +static size_t _mi_binx8(size_t bsize) { + if (bsize<=1) return bsize; + uint8_t b = mi_bsr32((uint32_t)bsize); + if (b <= 2) return bsize; + size_t bin = ((b << 2) | (bsize >> (b - 2))&0x03) - 5; + return bin; +} + +static void mi_bins(void) { + //printf(" QNULL(1), /* 0 */ \\\n "); + size_t last_bin = 0; + size_t min_bsize = 0; + size_t last_bsize = 0; + for (size_t bsize = 1; bsize < 2*1024; bsize++) { + size_t size = bsize * 64 * 1024; + size_t bin = _mi_binx8(bsize); + if (bin != last_bin) { + printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_bsize, last_bsize, last_bin); + //printf("QNULL(%6zd), ", wsize); + //if (last_bin%8 == 0) printf("/* %i */ \\\n ", last_bin); + last_bin = bin; + min_bsize = bsize; + } + last_bsize = bsize; + } +} +#endif \ No newline at end of file From ccbc8ae0bbfd71928dcb11b16ccad3c54c85e72d Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:46:28 -0800 Subject: [PATCH 02/29] 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 96008c55d0add668dbb09d135f6ca18a2f6a322e Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:57:30 -0800 Subject: [PATCH 03/29] fix ubsan warning on huge allocations (issue #543) --- src/segment.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/segment.c b/src/segment.c index c4cf9875..8d3eebe5 100644 --- a/src/segment.c +++ b/src/segment.c @@ -762,7 +762,8 @@ static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_i } // and also for the last one (if not set already) (the last one is needed for coalescing) - mi_slice_t* last = &segment->slices[slice_index + slice_count - 1]; + // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543) + mi_slice_t* last = &((mi_slice_t*)segment->slices)[slice_index + slice_count - 1]; if (last < mi_segment_slices_end(segment) && last >= slice) { last->slice_offset = (uint32_t)(sizeof(mi_slice_t)*(slice_count-1)); last->slice_count = 0; From 38639a08c8b75294fc18da05c7015eba88e2bbc5 Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 10 Feb 2022 11:58:25 -0800 Subject: [PATCH 04/29] 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 05/29] 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 06/29] 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 07/29] 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 08/29] 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 b89b4fd18a103eda7397cc7000b5ee5eda2f3cd8 Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:44:33 -0800 Subject: [PATCH 09/29] fix v2.0.5 version --- cmake/mimalloc-config-version.cmake | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake/mimalloc-config-version.cmake b/cmake/mimalloc-config-version.cmake index 76b2af6c..acbd0f70 100644 --- a/cmake/mimalloc-config-version.cmake +++ b/cmake/mimalloc-config-version.cmake @@ -1,12 +1,6 @@ -<<<<<<< HEAD set(mi_version_major 2) set(mi_version_minor 0) -set(mi_version_patch 4) -======= -set(mi_version_major 1) -set(mi_version_minor 7) set(mi_version_patch 5) ->>>>>>> dev set(mi_version ${mi_version_major}.${mi_version_minor}) set(PACKAGE_VERSION ${mi_version}) From ec2265486ecf1d1868afa76c68bcbb8b70dd8fac Mon Sep 17 00:00:00 2001 From: Daan Date: Mon, 14 Feb 2022 16:47:57 -0800 Subject: [PATCH 10/29] 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 11/29] 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 12/29] 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 13/29] 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 14/29] 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 15/29] 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 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 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 16/29] 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 17/29] 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 18/29] 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 19/29] 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 20/29] 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 21/29] 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 9f6cbc50eeb20a227fe1def30cb68be8e84b1c32 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 09:48:08 -0700 Subject: [PATCH 22/29] use heap_stat_decrease when possible --- src/page.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/page.c b/src/page.c index 94fc707d..abc73685 100644 --- a/src/page.c +++ b/src/page.c @@ -371,12 +371,12 @@ void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { const size_t bsize = mi_page_block_size(page); if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) { if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { - _mi_stat_decrease(&heap->tld->stats.large, bsize); + mi_heap_stat_decrease(heap, large, bsize); } else { // not strictly necessary as we never get here for a huge page mi_assert_internal(false); - _mi_stat_decrease(&heap->tld->stats.huge, bsize); + mi_heap_stat_decrease(heap, huge, bsize); } } From 049d37c349a349a576654a717d237c6e45991e3a Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 10:19:26 -0700 Subject: [PATCH 23/29] 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 24/29] 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 332346b685808db68b97e0870cbdc82c1ba6e76d Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 10:38:31 -0700 Subject: [PATCH 25/29] remove unneeded MI_HUGE_OBJ_SIZE_MAX --- include/mimalloc-types.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/mimalloc-types.h b/include/mimalloc-types.h index 310fb92b..0456884b 100644 --- a/include/mimalloc-types.h +++ b/include/mimalloc-types.h @@ -156,7 +156,6 @@ typedef int32_t mi_ssize_t; #define MI_MEDIUM_OBJ_WSIZE_MAX (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE) #define MI_LARGE_OBJ_SIZE_MAX (MI_SEGMENT_SIZE/2) // 32MiB on 64-bit #define MI_LARGE_OBJ_WSIZE_MAX (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE) -#define MI_HUGE_OBJ_SIZE_MAX (2*MI_INTPTR_SIZE*MI_SEGMENT_SIZE) // (must match MI_REGION_MAX_ALLOC_SIZE in memory.c) // Maximum number of size classes. (spaced exponentially in 12.5% increments) #define MI_BIN_HUGE (73U) @@ -175,7 +174,7 @@ typedef int32_t mi_ssize_t; #define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1) // Used as a special value to encode block sizes in 32 bits. -#define MI_HUGE_BLOCK_SIZE ((uint32_t)MI_HUGE_OBJ_SIZE_MAX) +#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB)) // blocks up to this size are always allocated aligned #define MI_MAX_ALIGN_GUARANTEE (8*MI_MAX_ALIGN_SIZE) From 0cda8b02d5bdaa6d23c8862729cce624d5f07964 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 11:08:54 -0700 Subject: [PATCH 26/29] fix stats for large objects that were off by the block size padding --- src/alloc.c | 24 +++++++++++++++--------- src/page.c | 13 +------------ 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 8cf72429..58115daa 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -45,7 +45,7 @@ extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t siz #if (MI_STAT>0) const size_t bsize = mi_page_usable_block_size(page); - if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { mi_heap_stat_increase(heap, normal, bsize); mi_heap_stat_counter_increase(heap, normal_count, 1); #if (MI_STAT>1) @@ -297,20 +297,26 @@ static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, co // only maintain stats for smaller objects if requested #if (MI_STAT>0) static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) { -#if (MI_STAT < 2) + #if (MI_STAT < 2) MI_UNUSED(block); -#endif + #endif mi_heap_t* const heap = mi_heap_get_default(); - const size_t bsize = mi_page_usable_block_size(page); -#if (MI_STAT>1) + const size_t bsize = mi_page_usable_block_size(page); + #if (MI_STAT>1) const size_t usize = mi_page_usable_size_of(page, block); mi_heap_stat_decrease(heap, malloc, usize); -#endif - if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + #endif + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { mi_heap_stat_decrease(heap, normal, bsize); -#if (MI_STAT > 1) + #if (MI_STAT > 1) mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], 1); -#endif + #endif + } + else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); } } #else diff --git a/src/page.c b/src/page.c index abc73685..1849dc8f 100644 --- a/src/page.c +++ b/src/page.c @@ -368,17 +368,6 @@ void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { mi_page_set_has_aligned(page, false); mi_heap_t* heap = mi_page_heap(page); - const size_t bsize = mi_page_block_size(page); - if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) { - if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { - mi_heap_stat_decrease(heap, large, bsize); - } - else { - // not strictly necessary as we never get here for a huge page - mi_assert_internal(false); - mi_heap_stat_decrease(heap, huge, bsize); - } - } // remove from the page list // (no need to do _mi_heap_delayed_free first as all blocks are already free) @@ -791,7 +780,7 @@ static mi_page_t* mi_large_huge_page_alloc(mi_heap_t* heap, size_t size) { mi_page_queue_t* pq = (is_huge ? NULL : mi_page_queue(heap, block_size)); mi_page_t* page = mi_page_fresh_alloc(heap, pq, block_size); if (page != NULL) { - const size_t bsize = mi_page_block_size(page); // note: not `mi_page_usable_block_size` as `size` includes padding + const size_t bsize = mi_page_usable_block_size(page); // note: includes padding mi_assert_internal(mi_page_immediate_available(page)); mi_assert_internal(bsize >= size); From a799b214a2429908cbfcb6e083b1606869c96696 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 7 Apr 2022 12:33:25 -0700 Subject: [PATCH 27/29] 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 28/29] 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 29/29] 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.