From 06042c079b38f004fcc5b227d6647f5b78d01783 Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Fri, 2 Oct 2020 10:17:12 +0100 Subject: [PATCH] added [std::]alloc_aligned/free redundency for restricted platforms, removed 'overrides' --- src/alloc-override-osx.c | 260 --------------------------------------- src/alloc-override.c | 214 -------------------------------- src/alloc.c | 6 +- src/os.c | 34 +++-- src/stats.c | 32 +---- 5 files changed, 35 insertions(+), 511 deletions(-) delete mode 100644 src/alloc-override-osx.c delete mode 100644 src/alloc-override.c diff --git a/src/alloc-override-osx.c b/src/alloc-override-osx.c deleted file mode 100644 index c1c880c..0000000 --- a/src/alloc-override-osx.c +++ /dev/null @@ -1,260 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 2018, Microsoft Research, Daan Leijen -This is free software; you can redistribute it and/or modify it under the -terms of the MIT license. A copy of the license can be found in the file -"LICENSE" at the root of this distribution. ------------------------------------------------------------------------------*/ - -#include "mimalloc.h" -#include "mimalloc-internal.h" - -#if defined(MI_MALLOC_OVERRIDE) - -#if !defined(__APPLE__) -#error "this file should only be included on macOS" -#endif - -/* ------------------------------------------------------ - Override system malloc on macOS - This is done through the malloc zone interface. - It seems we also need to interpose (see `alloc-override.c`) - or otherwise we get zone errors as there are usually - already allocations done by the time we take over the - zone. Unfortunately, that means we need to replace - the `free` with a checked free (`cfree`) impacting - performance. ------------------------------------------------------- */ - -#include -#include -#include // memset - -#if defined(MAC_OS_X_VERSION_10_6) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 -// only available from OSX 10.6 -extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import)); -#endif - - -/* ------------------------------------------------------ - malloc zone members ------------------------------------------------------- */ - -static size_t zone_size(malloc_zone_t* zone, const void* p) { - UNUSED(zone); - if (!mi_is_in_heap_region(p)) - return 0; // not our pointer, bail out - - return mi_usable_size(p); -} - -static void* zone_malloc(malloc_zone_t* zone, size_t size) { - UNUSED(zone); - return mi_malloc(size); -} - -static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) { - UNUSED(zone); - return mi_calloc(count, size); -} - -static void* zone_valloc(malloc_zone_t* zone, size_t size) { - UNUSED(zone); - return mi_malloc_aligned(size, _mi_os_page_size()); -} - -static void zone_free(malloc_zone_t* zone, void* p) { - UNUSED(zone); - return mi_free(p); -} - -static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { - UNUSED(zone); - return mi_realloc(p, newsize); -} - -static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) { - UNUSED(zone); - return mi_malloc_aligned(size,alignment); -} - -static void zone_destroy(malloc_zone_t* zone) { - UNUSED(zone); - // todo: ignore for now? -} - -static unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) { - size_t i; - for (i = 0; i < count; i++) { - ps[i] = zone_malloc(zone, size); - if (ps[i] == NULL) break; - } - return i; -} - -static void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) { - for(size_t i = 0; i < count; i++) { - zone_free(zone, ps[i]); - ps[i] = NULL; - } -} - -static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) { - UNUSED(zone); UNUSED(size); - mi_collect(false); - return 0; -} - -static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) { - UNUSED(size); - zone_free(zone,p); -} - - -/* ------------------------------------------------------ - Introspection members ------------------------------------------------------- */ - -static kern_return_t intro_enumerator(task_t task, void* p, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, - vm_range_recorder_t recorder) -{ - // todo: enumerate all memory - UNUSED(task); UNUSED(p); UNUSED(type_mask); UNUSED(zone_address); - UNUSED(reader); UNUSED(recorder); - return KERN_SUCCESS; -} - -static size_t intro_good_size(malloc_zone_t* zone, size_t size) { - UNUSED(zone); - return mi_good_size(size); -} - -static boolean_t intro_check(malloc_zone_t* zone) { - UNUSED(zone); - return true; -} - -static void intro_print(malloc_zone_t* zone, boolean_t verbose) { - UNUSED(zone); UNUSED(verbose); - mi_stats_print(NULL); -} - -static void intro_log(malloc_zone_t* zone, void* p) { - UNUSED(zone); UNUSED(p); - // todo? -} - -static void intro_force_lock(malloc_zone_t* zone) { - UNUSED(zone); - // todo? -} - -static void intro_force_unlock(malloc_zone_t* zone) { - UNUSED(zone); - // todo? -} - -static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { - UNUSED(zone); - // todo... - stats->blocks_in_use = 0; - stats->size_in_use = 0; - stats->max_size_in_use = 0; - stats->size_allocated = 0; -} - -static boolean_t intro_zone_locked(malloc_zone_t* zone) { - UNUSED(zone); - return false; -} - - -/* ------------------------------------------------------ - At process start, override the default allocator ------------------------------------------------------- */ - -static malloc_zone_t* mi_get_default_zone() -{ - // The first returned zone is the real default - malloc_zone_t** zones = NULL; - unsigned count = 0; - kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count); - if (ret == KERN_SUCCESS && count > 0) { - return zones[0]; - } - else { - // fallback - return malloc_default_zone(); - } -} - -static void __attribute__((constructor)) _mi_macos_override_malloc() -{ - static malloc_introspection_t intro; - memset(&intro, 0, sizeof(intro)); - - intro.enumerator = &intro_enumerator; - intro.good_size = &intro_good_size; - intro.check = &intro_check; - intro.print = &intro_print; - intro.log = &intro_log; - intro.force_lock = &intro_force_lock; - intro.force_unlock = &intro_force_unlock; - - static malloc_zone_t zone; - memset(&zone, 0, sizeof(zone)); - - zone.version = 4; - zone.zone_name = "mimalloc"; - zone.size = &zone_size; - zone.introspect = &intro; - zone.malloc = &zone_malloc; - zone.calloc = &zone_calloc; - zone.valloc = &zone_valloc; - zone.free = &zone_free; - zone.realloc = &zone_realloc; - zone.destroy = &zone_destroy; - zone.batch_malloc = &zone_batch_malloc; - zone.batch_free = &zone_batch_free; - - malloc_zone_t* purgeable_zone = NULL; - -#if defined(MAC_OS_X_VERSION_10_6) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - // switch to version 9 on OSX 10.6 to support memalign. - zone.version = 9; - zone.memalign = &zone_memalign; - zone.free_definite_size = &zone_free_definite_size; - zone.pressure_relief = &zone_pressure_relief; - intro.zone_locked = &intro_zone_locked; - intro.statistics = &intro_statistics; - - // force the purgeable zone to exist to avoid strange bugs - if (malloc_default_purgeable_zone) { - purgeable_zone = malloc_default_purgeable_zone(); - } -#endif - - // Register our zone - malloc_zone_register(&zone); - - // Unregister the default zone, this makes our zone the new default - // as that was the last registered. - malloc_zone_t *default_zone = mi_get_default_zone(); - malloc_zone_unregister(default_zone); - - // Reregister the default zone so free and realloc in that zone keep working. - malloc_zone_register(default_zone); - - // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs - // earlier than the default zone. - if (purgeable_zone != NULL) { - malloc_zone_unregister(purgeable_zone); - malloc_zone_register(purgeable_zone); - } - -} - -#endif // MI_MALLOC_OVERRIDE diff --git a/src/alloc-override.c b/src/alloc-override.c deleted file mode 100644 index ae7ad7d..0000000 --- a/src/alloc-override.c +++ /dev/null @@ -1,214 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 2018, Microsoft Research, Daan Leijen -This is free software; you can redistribute it and/or modify it under the -terms of the MIT license. A copy of the license can be found in the file -"LICENSE" at the root of this distribution. ------------------------------------------------------------------------------*/ - -#if !defined(MI_IN_ALLOC_C) -#error "this file should be included from 'alloc.c' (so aliases can work)" -#endif - -#if defined(MI_MALLOC_OVERRIDE) && defined(_WIN32) && !(defined(MI_SHARED_LIB) && defined(_DLL)) -#error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)" -#endif - -#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) // || (defined(__MACH__) && !defined(MI_INTERPOSE))) - -// ------------------------------------------------------ -// Override system malloc -// ------------------------------------------------------ - -#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) - // use aliasing to alias the exported function to one of our `mi_` functions - #if (defined(__GNUC__) && __GNUC__ >= 9) - #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun))) - #else - #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"))) - #endif - #define MI_FORWARD1(fun,x) MI_FORWARD(fun) - #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun) - #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun) - #define MI_FORWARD0(fun,x) MI_FORWARD(fun) - #define MI_FORWARD02(fun,x,y) MI_FORWARD(fun) -#else - // use forwarding by calling our `mi_` function - #define MI_FORWARD1(fun,x) { return fun(x); } - #define MI_FORWARD2(fun,x,y) { return fun(x,y); } - #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); } - #define MI_FORWARD0(fun,x) { fun(x); } - #define MI_FORWARD02(fun,x,y) { fun(x,y); } -#endif - -#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE) - // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` - // See: - struct mi_interpose_s { - const void* replacement; - const void* target; - }; - #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } - #define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) - __attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) = - { - MI_INTERPOSE_MI(malloc), - MI_INTERPOSE_MI(calloc), - MI_INTERPOSE_MI(realloc), - MI_INTERPOSE_MI(strdup), - MI_INTERPOSE_MI(strndup), - MI_INTERPOSE_MI(realpath), - MI_INTERPOSE_MI(posix_memalign), - MI_INTERPOSE_MI(reallocf), - MI_INTERPOSE_MI(valloc), - // some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity ) - MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us - }; -#elif defined(_MSC_VER) - // cannot override malloc unless using a dll. - // we just override new/delete which does work in a static library. -#else - // On all other systems forward to our API - void* malloc(size_t size) MI_FORWARD1(mi_malloc, size); - void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n); - void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize); - void free(void* p) MI_FORWARD0(mi_free, p); -#endif - -#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) -#pragma GCC visibility push(default) -#endif - -// ------------------------------------------------------ -// Override new/delete -// This is not really necessary as they usually call -// malloc/free anyway, but it improves performance. -// ------------------------------------------------------ -#ifdef __cplusplus - // ------------------------------------------------------ - // With a C++ compiler we override the new/delete operators. - // see - // ------------------------------------------------------ - #include - void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p); - void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p); - - void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); - void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); - - void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } - void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } - - #if (__cplusplus >= 201402L || _MSC_VER >= 1916) - void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); - void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); - #endif - - #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5)) - void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } - 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 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 - -#elif (defined(__GNUC__) || defined(__clang__)) - // ------------------------------------------------------ - // Override by defining the mangled C++ names of the operators (as - // used by GCC and CLang). - // See - // ------------------------------------------------------ - void _ZdlPv(void* p) MI_FORWARD0(mi_free,p); // delete - void _ZdaPv(void* p) MI_FORWARD0(mi_free,p); // delete[] - void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); - void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); - void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } - void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } - void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } - void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } - - typedef struct mi_nothrow_s { } mi_nothrow_t; - #if (MI_INTPTR_SIZE==8) - void* _Znwm(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit - void* _Znam(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit - void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); - void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); - void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } - void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } - void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } - void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } - #elif (MI_INTPTR_SIZE==4) - void* _Znwj(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit - void* _Znaj(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit - void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); - void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); - void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } - void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } - void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } - void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } - #else - #error "define overloads for new/delete for this platform (just for performance, can be skipped)" - #endif -#endif // __cplusplus - - -#ifdef __cplusplus -extern "C" { -#endif - -// ------------------------------------------------------ -// Posix & Unix functions definitions -// ------------------------------------------------------ - -void cfree(void* p) MI_FORWARD0(mi_free, p); -void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize); -size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p); -#if !defined(__ANDROID__) -size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p); -#else -size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p); -#endif - -// no forwarding here due to aliasing/name mangling issues -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); } -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); } - -// on some glibc `aligned_alloc` is declared `static inline` so we cannot override it (e.g. Conda). This happens -// when _GLIBCXX_HAVE_ALIGNED_ALLOC is not defined. However, in those cases it will use `memalign`, `posix_memalign`, -// or `_aligned_malloc` and we can avoid overriding it ourselves. -// We should always override if using C compilation. (issue #276) -#if _GLIBCXX_HAVE_ALIGNED_ALLOC || !defined(__cplusplus) -void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } -#endif - - -#if defined(__GLIBC__) && defined(__linux__) - // forward __libc interface (needed for glibc-based Linux distributions) - void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size); - void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size); - void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size); - void __libc_free(void* p) MI_FORWARD0(mi_free,p); - void __libc_cfree(void* p) MI_FORWARD0(mi_free,p); - - void* __libc_valloc(size_t size) { return mi_valloc(size); } - void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); } - void* __libc_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); } -#endif - -#ifdef __cplusplus -} -#endif - -#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) -#pragma GCC visibility pop -#endif - -#endif // MI_MALLOC_OVERRIDE && !_WIN32 diff --git a/src/alloc.c b/src/alloc.c index 8e863a6..b093345 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4,16 +4,16 @@ This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ +#include "AuroraEnvrionment.hpp" + #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" + #include // memset, memcpy, strlen #include // malloc, exit -#define MI_IN_ALLOC_C -#include "alloc-override.c" -#undef MI_IN_ALLOC_C // ------------------------------------------------------ // Allocation diff --git a/src/os.c b/src/os.c index 6985587..b51d36a 100644 --- a/src/os.c +++ b/src/os.c @@ -4,6 +4,8 @@ This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ +#include "AuroraEnvrionment.hpp" + #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE // ensure mmap flags are defined #endif @@ -20,6 +22,10 @@ terms of the MIT license. A copy of the license can be found in the file #include "mimalloc-internal.h" #include "mimalloc-atomic.h" +#if defined(_AURORA_MEM_STRICT) +#include // std allocation +#endif + #include // strerror #ifdef _MSC_VER @@ -227,7 +233,10 @@ 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) +#if defined(_AURORA_MEM_STRICT) + free(addr); + err = 0; +#elif defined(_WIN32) err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); #elif defined(__wasi__) err = 0; // WebAssembly's heap cannot be shrunk @@ -247,7 +256,9 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size); -#ifdef _WIN32 +#if defined(_AURORA_MEM_STRICT) + +#elif defined(_WIN32) static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment, DWORD flags) { #if (MI_INTPTR_SIZE >= 8) // on 64-bit systems, try to use the virtual address area after 4TiB for 4MiB aligned allocations @@ -508,8 +519,9 @@ static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, boo } } */ - - #if defined(_WIN32) + #if defined(_AURORA_MEM_STRICT) + return aligned_alloc(try_alignment, size); + #elif defined(_WIN32) int flags = MEM_RESERVE; if (commit) flags |= MEM_COMMIT; p = mi_win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); @@ -698,7 +710,9 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ _mi_stat_decrease(&stats->committed, size); } - #if defined(_WIN32) + #if defined(_AURORA_MEM_STRICT) + // optional low level control. we can't control the MMIO from the CRT + #elif defined(_WIN32) if (commit) { // if the memory was already committed, the call succeeds but it is not zero'd // *is_zero = true; @@ -770,7 +784,9 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats) } #endif -#if defined(_WIN32) + #if defined(_AURORA_MEM_STRICT) + // optional low level control. we can't control the MMIO from the CRT + #elif defined(_WIN32) // Testing shows that for us (on `malloc-large`) MEM_RESET is 2x faster than DiscardVirtualMemory void* p = VirtualAlloc(start, csize, MEM_RESET, PAGE_READWRITE); mi_assert_internal(p == start); @@ -843,7 +859,9 @@ static bool mi_os_protectx(void* addr, size_t size, bool protect) { } */ int err = 0; -#ifdef _WIN32 +#if defined(_AURORA_MEM_STRICT) + // optional low level control. we can't control the MMIO from the CRT +#elif defined(_WIN32) DWORD oldprotect = 0; BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect); err = (ok ? 0 : GetLastError()); @@ -882,7 +900,7 @@ bool _mi_os_shrink(void* p, size_t oldsize, size_t newsize, mi_stats_t* stats) { void* start = mi_os_page_align_area_conservative(addr, oldsize - newsize, &size); if (size == 0 || start != addr) return false; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_AURORA_MEM_STRICT) // we cannot shrink on windows, but we can decommit return _mi_os_decommit(start, size, stats); #else diff --git a/src/stats.c b/src/stats.c index b04822c..d2fe06f 100644 --- a/src/stats.c +++ b/src/stats.c @@ -4,6 +4,8 @@ This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ +#include "AuroraEnvrionment.hpp" + #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" @@ -442,7 +444,7 @@ mi_msecs_t _mi_clock_end(mi_msecs_t start) { // Basic process statistics // -------------------------------------------------------- -#if defined(_WIN32) +#if defined(AURORA_PLATFORM_WIN32) #include #include #pragma comment(lib,"psapi.lib") @@ -474,7 +476,7 @@ static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msec *page_faults = (size_t)info.PageFaultCount; } -#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) +#elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_APPLE) #include #include #include @@ -498,40 +500,18 @@ static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msec getrusage(RUSAGE_SELF, &rusage); *utime = timeval_secs(&rusage.ru_utime); *stime = timeval_secs(&rusage.ru_stime); -#if !defined(__HAIKU__) *page_faults = rusage.ru_majflt; -#endif + // estimate commit using our stats *peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); *current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); *current_rss = *current_commit; // estimate -#if defined(__HAIKU__) - // Haiku does not have (yet?) a way to - // get these stats per process - thread_info tid; - area_info mem; - ssize_t c; - get_thread_info(find_thread(0), &tid); - while (get_next_area_info(tid.team, &c, &mem) == B_OK) { - *peak_rss += mem.ram_size; - } -#elif defined(__APPLE__) && defined(__MACH__) - *peak_rss = rusage.ru_maxrss; // BSD reports in bytes - struct mach_task_basic_info info; - mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; - if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { - *current_rss = (size_t)info.resident_size; - } -#else +#if defined(AURORA_PLATFORM_LINUX) *peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB #endif } #else -#ifndef __wasi__ -// WebAssembly instances are not processes -#pragma message("define a way to get process info") -#endif static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) {