From 71b2c441bb236fd43a1695e80af68ef750cddd0c Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Fri, 25 Jun 2021 10:09:19 +0800 Subject: [PATCH 01/10] CI: Update the macOS image to version 10.15 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index aeb2908b..65ceb30b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -115,7 +115,7 @@ jobs: displayName: macOS pool: vmImage: - macOS-10.14 + macOS-10.15 strategy: matrix: Debug: From c4947c887903ab216589a763013d2b22cf6457ac Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Sat, 24 Apr 2021 06:24:06 +0800 Subject: [PATCH 02/10] Use secure random generator on macOS The implementation of arc4random_buf differs from its documentation. It is documented as "always successful, and no return value is reserved to indicate an error" for the sake of FreeBSD compatibility [1]. However, the actual implementation on macOS invokes function "ccrng_generate" [2] without validating the error cases. It might fail silently[3], which leads to unexpected source of entropy. The original arc4random used the RC4 a.k.a. ARC4 algorithm, and ChaCha20 based implementation was introduced in FreeBSD 12.0. Since macOS 10.12, it was replaced with the NIST-approved AES cipher, and it may be replaced again in the future as cryptographic techniques advance. Therefore, we should not assume that arc4random never fails. On the contrary, CCRandomGenerateBytes(), part of Cryptographic Services [4], returns cryptographically strong random bits with explicit status code. This patch properly calls CCRandomGenerateBytes() and checks the status. [1] https://www.freebsd.org/cgi/man.cgi?query=arc4random_buf [2] https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60178.40.2/lib/CommonRandom.c.auto.html [3] https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html [4] https://developer.apple.com/documentation/security --- src/random.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/random.c b/src/random.c index 255bede4..910a3e89 100644 --- a/src/random.c +++ b/src/random.c @@ -156,7 +156,8 @@ uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { /* ---------------------------------------------------------------------------- To initialize a fresh random context we rely on the OS: - Windows : BCryptGenRandom (or RtlGenRandom) -- osX,bsd,wasi: arc4random_buf +- macOS : CCRandomGenerateBytes +- bsd,wasi : arc4random_buf - Linux : getrandom,/dev/urandom If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. -----------------------------------------------------------------------------*/ @@ -186,7 +187,36 @@ static bool os_random_buf(void* buf, size_t buf_len) { } #endif -#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \ +#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 +#endif +static bool os_random_buf(void* buf, size_t buf_len) { + /* The implementation of arc4random_buf(3) differs from its documentation. + * It is documented as "always successful, and no return value is reserved + * to indicate an error." However, the actual implementation invokes the + * function "ccrng_generate" without validating the error cases. It might + * fail silently, which leads to unexpected source of entropy. + * See: + * https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html + * + * CCRandomGenerateBytes(), on the contrary, returns cryptographically strong + * random bits with explicit status code. + */ +#if defined(MAC_OS_X_VERSION_10_15) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + return CCRandomGenerateBytes(buf, buf_len) == kCCSuccess; +#else + /* Prior to macOS 10.15, CCRandomGenerateBytes() might take a bit longer time + * to complete, so failback to arc4random_buf(). + */ + arc4random_buf(buf, buf_len); + return true; +#endif +} +#elif defined(ANDROID) || defined(__DragonFly__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__sun) || defined(__wasi__) #include From 20e37bf7c1ce89515b38bb82aa6b8b3838b9c456 Mon Sep 17 00:00:00 2001 From: DC Date: Sun, 28 Nov 2021 08:14:21 +0000 Subject: [PATCH 03/10] removes dragonflybsd warning since the api and library overriding works, also for the os doc report purpose. --- include/mimalloc-internal.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index cf5b6783..e22953d4 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -314,9 +314,6 @@ mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing hea // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16) // see #define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24) -#elif defined(__DragonFly__) -#warning "mimalloc is not working correctly on DragonFly yet." -//#define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) #endif #endif From d6a56dd99d5abe4e1f6af555976ee8dc64e1ec8a Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 1 Dec 2021 22:43:13 +0000 Subject: [PATCH 04/10] introduces netbsd's reallocarr overriding. and couple of tests. --- include/mimalloc-override.h | 1 + include/mimalloc.h | 1 + src/alloc-override.c | 1 + src/alloc-posix.c | 14 ++++++++++++++ test/main-override.c | 8 +++++++- 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/mimalloc-override.h b/include/mimalloc-override.h index 2362bfbc..c00fc594 100644 --- a/include/mimalloc-override.h +++ b/include/mimalloc-override.h @@ -48,6 +48,7 @@ not accidentally mix pointers from different allocators). #define valloc(n) mi_valloc(n) #define pvalloc(n) mi_pvalloc(n) #define reallocarray(p,s,n) mi_reallocarray(p,s,n) +#define reallocarr(p,s,n) mi_reallocarr(p,s,n) #define memalign(a,n) mi_memalign(a,n) #define aligned_alloc(a,n) mi_aligned_alloc(a,n) #define posix_memalign(p,a,n) mi_posix_memalign(p,a,n) diff --git a/include/mimalloc.h b/include/mimalloc.h index a2835d02..414d628d 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -351,6 +351,7 @@ mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export int mi_reallocarr(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; diff --git a/src/alloc-override.c b/src/alloc-override.c index 5906bd20..d24cd8bc 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -183,6 +183,7 @@ size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p); void* valloc(size_t size) { return mi_valloc(size); } void* pvalloc(size_t size) { return mi_pvalloc(size); } void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } +int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(&p, count, size); } void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); } void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } diff --git a/src/alloc-posix.c b/src/alloc-posix.c index eef70ab5..6465304c 100644 --- a/src/alloc-posix.c +++ b/src/alloc-posix.c @@ -90,6 +90,20 @@ void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { return newp; } +int mi_reallocarr( void* p, size_t count, size_t size ) mi_attr_noexcept { // NetBSD + void** op = (void** )p; + int serrno = errno; + void* newp = mi_reallocn(p,count,size); + if (mi_unlikely(newp == NULL)) { + errno = ENOMEM; + return errno; + } else { + *op = newp; + errno = serrno; + return 0; + } +} + void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft void* res = mi_expand(p, newsize); if (res == NULL) errno = ENOMEM; diff --git a/test/main-override.c b/test/main-override.c index 1bec1179..284fdd20 100644 --- a/test/main-override.c +++ b/test/main-override.c @@ -3,7 +3,7 @@ #include #include -#include +#include int main() { mi_version(); // ensure mimalloc library is linked @@ -25,6 +25,12 @@ int main() { //free(p1); //p2 = malloc(32); //mi_free(p2); + p1 = malloc(24); + p2 = reallocarray(p1, 16, 16); + free(p2); + p1 = malloc(24); + assert(reallocarr(&p1, 16, 16) == 0); + free(p1); mi_stats_print(NULL); return 0; } From 523e6d5c9b251bc8d969a685b2b6feda6fd1f8ab Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 16:05:07 -0800 Subject: [PATCH 05/10] fix thread slot on arm32 (issue #495) --- include/mimalloc-internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 4713a75e..324ad4a3 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -766,8 +766,8 @@ static inline void mi_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { } static inline mi_threadid_t _mi_thread_id(void) mi_attr_noexcept { -#if defined(__BIONIC__) && (defined(__arm__) || defined(__aarch64__)) - // on Android, slot 1 is the thread ID (pointer to pthread internal struct) +#if defined(__arm__) || (defined(__BIONIC__) && defined(__aarch64__)) + // issue #384, #495: on arm32 and arm32/arm64 Android, slot 1 is the thread ID (pointer to pthread internal struct) return (uintptr_t)mi_tls_slot(1); #else // in all our other targets, slot 0 is the pointer to the thread control block From 9fbf83c4332da1cd1b788a7592d0f80ca52c6b1b Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 16:32:26 -0800 Subject: [PATCH 06/10] fix reallocarr indirection (see #492) --- src/alloc-posix.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/alloc-posix.c b/src/alloc-posix.c index 6627d2b7..2eaede07 100644 --- a/src/alloc-posix.c +++ b/src/alloc-posix.c @@ -92,27 +92,23 @@ mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_n void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD void* newp = mi_reallocn(p,count,size); - if (newp==NULL) errno = ENOMEM; + if (newp==NULL) { errno = ENOMEM; } return newp; } int mi_reallocarr( void* p, size_t count, size_t size ) mi_attr_noexcept { // NetBSD - void** op = (void** )p; - int serrno = errno; - void* newp = mi_reallocn(p,count,size); - if (mi_unlikely(newp == NULL)) { - errno = ENOMEM; - return errno; - } else { - *op = newp; - errno = serrno; - return 0; - } + mi_assert(p != NULL); + if (p == NULL) return EINVAL; // should we set errno as well? + void** op = (void**)p; + void* newp = mi_reallocarray(*op, count, size); + if (mi_unlikely(newp == NULL)) return errno; + *op = newp; + return 0; } void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft void* res = mi_expand(p, newsize); - if (res == NULL) errno = ENOMEM; + if (res == NULL) { errno = ENOMEM; } return res; } From a8b5106ce21bd8ac957249c5a67f80b6eee52187 Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 16:33:49 -0800 Subject: [PATCH 07/10] fix address dereference in mi_reallocarr override --- src/alloc-override.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alloc-override.c b/src/alloc-override.c index eab202aa..6bbe4aac 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -245,7 +245,7 @@ extern "C" { void cfree(void* p) { mi_free(p); } void* pvalloc(size_t size) { return mi_pvalloc(size); } void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } -int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(&p, count, size); } +int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(p, count, size); } void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } From 317093d78b9dea347ceeaf15775c74e78e0e5fc7 Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 16:48:57 -0800 Subject: [PATCH 08/10] fix Android overriding (issue #381 and PR #487) --- include/mimalloc-internal.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 324ad4a3..b8fc754f 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -317,6 +317,9 @@ mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing hea #elif defined(__DragonFly__) #warning "mimalloc is not working correctly on DragonFly yet." //#define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) +#elif defined(__ANDROID__) +// See issue #381 +#define MI_TLS_PTHREAD #endif #endif @@ -766,7 +769,7 @@ static inline void mi_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { } static inline mi_threadid_t _mi_thread_id(void) mi_attr_noexcept { -#if defined(__arm__) || (defined(__BIONIC__) && defined(__aarch64__)) +#if defined(__arm__) || (defined(__ANDROID__) && defined(__aarch64__)) // issue #384, #495: on arm32 and arm32/arm64 Android, slot 1 is the thread ID (pointer to pthread internal struct) return (uintptr_t)mi_tls_slot(1); #else From 0e851de2babfc32cfe85963f75c20f17dba6f4c5 Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 17:06:09 -0800 Subject: [PATCH 09/10] shorten comments for pr #390 --- src/random.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/random.c b/src/random.c index ff1ecced..e47946a6 100644 --- a/src/random.c +++ b/src/random.c @@ -160,7 +160,7 @@ uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { /* ---------------------------------------------------------------------------- To initialize a fresh random context we rely on the OS: - Windows : BCryptGenRandom (or RtlGenRandom) -- macOS : CCRandomGenerateBytes +- macOS : CCRandomGenerateBytes, arc4random_buf - bsd,wasi : arc4random_buf - Linux : getrandom,/dev/urandom If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. @@ -194,34 +194,22 @@ 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 +#if defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 #include #endif static bool os_random_buf(void* buf, size_t buf_len) { - /* The implementation of arc4random_buf(3) differs from its documentation. - * It is documented as "always successful, and no return value is reserved - * to indicate an error." However, the actual implementation invokes the - * function "ccrng_generate" without validating the error cases. It might - * fail silently, which leads to unexpected source of entropy. - * See: - * https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/FreeBSD/arc4random.c.auto.html - * - * CCRandomGenerateBytes(), on the contrary, returns cryptographically strong - * random bits with explicit status code. - */ -#if defined(MAC_OS_X_VERSION_10_15) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 - return CCRandomGenerateBytes(buf, buf_len) == kCCSuccess; -#else - /* Prior to macOS 10.15, CCRandomGenerateBytes() might take a bit longer time - * to complete, so failback to arc4random_buf(). - */ - arc4random_buf(buf, buf_len); - return true; -#endif + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + // We prefere CCRandomGenerateBytes as it returns an error code while arc4random_buf + // may fail silently on macOS. See PR #390, and + return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess); + #else + // fall back on older macOS + arc4random_buf(buf, buf_len); + return true; + #endif } -#elif defined(ANDROID) || defined(__DragonFly__) || \ + +#elif defined(__ANDROID__) || defined(__DragonFly__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__sun) // todo: what to use with __wasi__? #include From 8612d1228a76c306898e784fe0a1829ab67d4cd2 Mon Sep 17 00:00:00 2001 From: Daan Date: Wed, 15 Dec 2021 18:04:02 -0800 Subject: [PATCH 10/10] wip: initial fix for race condition on sbrk/wasm_memory_grow; issue #497 --- src/os.c | 87 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/src/os.c b/src/os.c index 603ec04a..dc2afc78 100644 --- a/src/os.c +++ b/src/os.c @@ -375,42 +375,69 @@ static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, return p; } -#elif defined(MI_USE_SBRK) +#elif defined(MI_USE_SBRK) || defined(__wasi__) + +#if defined(MI_USE_SBRK) #define MI_SBRK_FAIL ((void*)(-1)) -static void* mi_sbrk_heap_grow(size_t size, size_t try_alignment) { - void* pbase0 = sbrk(0); - if (pbase0 == MI_SBRK_FAIL) { +static void* mi_memory_grow( size_t size ) { + void* p = sbrk(size); + if (p == MI_SBRK_FAIL) { _mi_warning_message("unable to allocate sbrk() OS memory (%zu bytes)\n", size); errno = ENOMEM; return NULL; } - uintptr_t base = (uintptr_t)pbase0; - uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment); - size_t alloc_size = _mi_align_up( aligned_base - base + size, _mi_os_page_size()); - mi_assert(alloc_size >= size && (alloc_size % _mi_os_page_size()) == 0); - if (alloc_size < size) return NULL; - void* pbase1 = sbrk(alloc_size); - if (pbase1 == MI_SBRK_FAIL) { - _mi_warning_message("unable to allocate sbrk() OS memory (%zu bytes, %zu requested)\n", size, alloc_size); - errno = ENOMEM; - return NULL; - } - mi_assert(pbase0 == pbase1); - return (void*)aligned_base; + return p; } +#elif defined(__wasi__) +static void* mi_memory_grow( size_t size ) { + if (size > 0) { + size_t base = __builtin_wasm_memory_grow( 0, _mi_divide_up(size, _mi_os_page_size()) ); + if (base == SIZE_MAX) { + _mi_warning_message("unable to allocate wasm_memory_grow OS memory (%zu bytes)\n", size); + errno = ENOMEM; + return NULL; + } + return (void*)(base * _mi_os_page_size()); + } + else { + size_t base = __builtin_wasm_memory_size(0); + if (base == SIZE_MAX) { + errno = ENOMEM; + return NULL; + } + return (void*)(base * _mi_os_page_size()); + } +} +#endif -#elif defined(__wasi__) - // currently unused as we use sbrk() on wasm -static void* mi_wasm_heap_grow(size_t size, size_t try_alignment) { - uintptr_t base = __builtin_wasm_memory_size(0) * _mi_os_page_size(); - uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment); +static void* mi_heap_grow(size_t size, size_t try_alignment) { + if (try_alignment == 0) { try_alignment = _mi_os_page_size(); }; + void* pbase0 = mi_memory_grow(0); + if (pbase0 == NULL) { return NULL; } + uintptr_t base = (uintptr_t)pbase0; + uintptr_t aligned_base = _mi_align_up(base, try_alignment); size_t alloc_size = _mi_align_up( aligned_base - base + size, _mi_os_page_size()); mi_assert(alloc_size >= size && (alloc_size % _mi_os_page_size()) == 0); if (alloc_size < size) return NULL; - if (__builtin_wasm_memory_grow(0, alloc_size / _mi_os_page_size()) == SIZE_MAX) { - _mi_warning_message("unable to allocate wasm_memory_grow() OS memory (%zu bytes, %zu requested)\n", size, alloc_size); - errno = ENOMEM; - return NULL; + void* pbase1 = mi_memory_grow(alloc_size); + if (pbase1 == NULL) { return NULL; } + if (pbase0 != pbase1) { + // another thread allocated in-between; now we may not be able to align correctly + base = (uintptr_t)pbase1; + aligned_base = _mi_align_up(base, try_alignment); + if (aligned_base + size > base + alloc_size) { + // we do not have enough space after alignment; since we cannot shrink safely, + // we waste the space :-( and allocate fresh with guaranteed enough overallocation + alloc_size = _mi_align_up( size + try_alignment, _mi_os_page_size() ); + errno = 0; + void* pbase2 = mi_memory_grow( alloc_size ); + if (pbase2 == NULL) { return NULL; } + aligned_base = _mi_align_up(base, try_alignment); + mi_assert_internal(aligned_base + size <= (uintptr_t)pbase2 + alloc_size); + } + } + else { + mi_assert_internal(aligned_base + size <= (uintptr_t)pbase1 + alloc_size); } return (void*)aligned_base; } @@ -637,14 +664,10 @@ static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, boo int flags = MEM_RESERVE; 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) + #elif defined(MI_USE_SBRK) || defined(__wasi__) MI_UNUSED(allow_large); *is_large = false; - p = mi_sbrk_heap_grow(size, try_alignment); - #elif defined(__wasi__) - MI_UNUSED(allow_large); - *is_large = false; - p = mi_wasm_heap_grow(size, try_alignment); + p = mi_heap_grow(size, try_alignment); #else int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE); p = mi_unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large);