From b3e956baea2abe4ffc89e8250ad3c968b2144de7 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 12:12:05 +0800 Subject: [PATCH 01/17] [2_1] test of memory leakage in certain case --- tests/System/Memory/fast_alloc_test.cpp | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 8503ce540..2af0aa087 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -78,21 +78,23 @@ TEST_CASE ("test class") { TEST_CASE ("test tm_*_array") { uint8_t* p_complex= tm_new_array (100); tm_delete_array (p_complex); -#ifdef OS_WASM - const size_t size_prim= 200, size_complex= 100; -#else - const size_t size_prim= 20000000, size_complex= 5000000; -#endif - p_complex= tm_new_array (size_prim); + p_complex= tm_new_array (20000000); tm_delete_array (p_complex); - Complex* p_wide= tm_new_array (size_complex); + Complex* p_wide= tm_new_array (5000000); tm_delete_array (p_wide); } -#ifndef OS_WASM -TEST_CASE ("test large bunch of tm_*") { - const int bnum= 100000; - int* volume[bnum]; +TEST_MEMORY_LEAK_ALL +TEST_MEMORY_LEAK_RESET + +TEST_CASE ("test tm_*") { + const int bnum= +#ifdef OS_WASM + 1000; +#else + 100000; +#endif + int* volume[bnum]; for (int i= 0; i < bnum; i++) { volume[i]= tm_new (35); } @@ -100,11 +102,11 @@ TEST_CASE ("test large bunch of tm_*") { tm_delete (volume[i]); } } + TEST_MEMORY_LEAK_ALL TEST_MEMORY_LEAK_RESET -#endif -TEST_CASE ("test large bunch of tm_*_array with class") { +TEST_CASE ("test tm_*_array with class") { Complex* volume[NUM]; for (int i= 0; i < NUM; i++) { volume[i]= tm_new_array (9); From b7c944b431fd6378425c7e2a716e0e61e605d272 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 12:22:37 +0800 Subject: [PATCH 02/17] shrink size on wasm --- tests/System/Memory/fast_alloc_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 2af0aa087..db0ba688e 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -90,7 +90,7 @@ TEST_MEMORY_LEAK_RESET TEST_CASE ("test tm_*") { const int bnum= #ifdef OS_WASM - 1000; + 800; #else 100000; #endif From 18830e66603cc2e71db0465e94c0bb7340f637a3 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 13:56:26 +0800 Subject: [PATCH 03/17] fix memory leak caused by tail of trunk --- tests/System/Memory/fast_alloc_test.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index db0ba688e..57ac401b7 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -84,13 +84,10 @@ TEST_CASE ("test tm_*_array") { tm_delete_array (p_wide); } -TEST_MEMORY_LEAK_ALL -TEST_MEMORY_LEAK_RESET - TEST_CASE ("test tm_*") { const int bnum= #ifdef OS_WASM - 800; + 200; #else 100000; #endif @@ -103,9 +100,6 @@ TEST_CASE ("test tm_*") { } } -TEST_MEMORY_LEAK_ALL -TEST_MEMORY_LEAK_RESET - TEST_CASE ("test tm_*_array with class") { Complex* volume[NUM]; for (int i= 0; i < NUM; i++) { From b78282fa37b19d653ca7876a8e94be657d70983f Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 15:02:05 +0800 Subject: [PATCH 04/17] fix format and wasm issue --- tests/System/Memory/fast_alloc_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 57ac401b7..b172278b0 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -87,7 +87,7 @@ TEST_CASE ("test tm_*_array") { TEST_CASE ("test tm_*") { const int bnum= #ifdef OS_WASM - 200; + 1 00; #else 100000; #endif From 07dd6ceedb20bdfd7c57ef1e9cf84deb3f350690 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 15:41:15 +0800 Subject: [PATCH 05/17] fix failure on wasm --- tests/System/Memory/fast_alloc_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index b172278b0..ccff634f7 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -87,7 +87,7 @@ TEST_CASE ("test tm_*_array") { TEST_CASE ("test tm_*") { const int bnum= #ifdef OS_WASM - 1 00; + 150; #else 100000; #endif From dd8d0433123591f073ee35488ed151acf913c767 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 15:50:49 +0800 Subject: [PATCH 06/17] disable tests of tm_new --- tests/System/Memory/fast_alloc_test.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index ccff634f7..477e3c948 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -84,14 +84,10 @@ TEST_CASE ("test tm_*_array") { tm_delete_array (p_wide); } -TEST_CASE ("test tm_*") { - const int bnum= -#ifdef OS_WASM - 150; -#else - 100000; -#endif - int* volume[bnum]; +#ifndef OS_WASM +TEST_CASE ("test large bunch of tm_*") { + const int bnum= 100000; + int* volume[bnum]; for (int i= 0; i < bnum; i++) { volume[i]= tm_new (35); } @@ -99,8 +95,9 @@ TEST_CASE ("test tm_*") { tm_delete (volume[i]); } } +#endif -TEST_CASE ("test tm_*_array with class") { +TEST_CASE ("test large bunch of tm_*_array with class") { Complex* volume[NUM]; for (int i= 0; i < NUM; i++) { volume[i]= tm_new_array (9); From eaea5d5478d22b4b8bcdfccbf9cd4524aeacf657 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Wed, 1 Nov 2023 16:28:46 +0800 Subject: [PATCH 07/17] fix 2nd --- tests/System/Memory/fast_alloc_test.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 477e3c948..8503ce540 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -78,9 +78,14 @@ TEST_CASE ("test class") { TEST_CASE ("test tm_*_array") { uint8_t* p_complex= tm_new_array (100); tm_delete_array (p_complex); - p_complex= tm_new_array (20000000); +#ifdef OS_WASM + const size_t size_prim= 200, size_complex= 100; +#else + const size_t size_prim= 20000000, size_complex= 5000000; +#endif + p_complex= tm_new_array (size_prim); tm_delete_array (p_complex); - Complex* p_wide= tm_new_array (5000000); + Complex* p_wide= tm_new_array (size_complex); tm_delete_array (p_wide); } @@ -95,6 +100,8 @@ TEST_CASE ("test large bunch of tm_*") { tm_delete (volume[i]); } } +TEST_MEMORY_LEAK_ALL +TEST_MEMORY_LEAK_RESET #endif TEST_CASE ("test large bunch of tm_*_array with class") { From e6010480507641e3fe461bfcbbaffd636789c911 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Thu, 2 Nov 2023 19:20:05 +0800 Subject: [PATCH 08/17] make use of mimalloc and jemalloc --- System/Memory/fast_alloc.hpp | 6 - System/Memory/{ => impl}/fast_alloc.cpp | 0 System/Memory/impl/je_malloc.cpp | 140 +++++++++++++++++++++ System/Memory/impl/mi_malloc.cpp | 159 ++++++++++++++++++++++++ tests/System/Memory/fast_alloc_test.cpp | 26 ++++ xmake.lua | 10 +- 6 files changed, 331 insertions(+), 10 deletions(-) rename System/Memory/{ => impl}/fast_alloc.cpp (100%) create mode 100644 System/Memory/impl/je_malloc.cpp create mode 100644 System/Memory/impl/mi_malloc.cpp diff --git a/System/Memory/fast_alloc.hpp b/System/Memory/fast_alloc.hpp index ba682fcfc..41f46d446 100644 --- a/System/Memory/fast_alloc.hpp +++ b/System/Memory/fast_alloc.hpp @@ -13,12 +13,6 @@ #define FAST_ALLOC_H #include -#ifdef MIMALLOC -#include "mimalloc-override.h" -#endif -#ifdef JEMALLOC -#include "jemalloc/jemalloc.h" -#endif #include "tm_ostream.hpp" #define WORD_LENGTH 8 #define WORD_LENGTH_INC 7 diff --git a/System/Memory/fast_alloc.cpp b/System/Memory/impl/fast_alloc.cpp similarity index 100% rename from System/Memory/fast_alloc.cpp rename to System/Memory/impl/fast_alloc.cpp diff --git a/System/Memory/impl/je_malloc.cpp b/System/Memory/impl/je_malloc.cpp new file mode 100644 index 000000000..05b498902 --- /dev/null +++ b/System/Memory/impl/je_malloc.cpp @@ -0,0 +1,140 @@ + +/****************************************************************************** + * MODULE : Fast memory allocation using mimalloc + * DESCRIPTION: + * COPYRIGHT : (C) 1999 Joris van der Hoeven + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +#include "fast_alloc.hpp" +#include "assert.h" +#include "jemalloc/jemalloc.h" + +int mem_used (); + +/*****************************************************************************/ +// General purpose fast allocation routines +/*****************************************************************************/ + +void* +safe_malloc (size_t sz) { + void* ptr= malloc (sz); + + if (ptr == NULL) { + cerr << "Fatal error: out of memory\n"; + abort (); + } + return ptr; +} + +void* +enlarge_malloc (size_t sz) { + return NULL; +} + +void* +fast_alloc (size_t sz) { + return safe_malloc (sz); +} + +void +fast_free (void* ptr, size_t sz) { + free (ptr); +} + +void* +fast_new (size_t s) { + return safe_malloc (s); +} + +void +fast_delete (void* ptr) { + free (ptr); +} + +/****************************************************************************** + * Statistics + ******************************************************************************/ + +int +mem_used () { + return 0; +} + +void +mem_info () { + cout << "\n---------------- memory statistics ----------------\n"; +} + +/****************************************************************************** + * Redefine standard new and delete + ******************************************************************************/ + +#if defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) + +void* +operator new (size_t s) { + void* ptr; + s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; + if (s < MAX_FAST) { + ptr= alloc_ptr (s); + if (ptr == NULL) ptr= enlarge_malloc (s); + else alloc_ptr (s)= ind (ptr); + } + else { + ptr= safe_malloc (s); + large_uses+= s; + } + *((size_t*) ptr)= s; + return (void*) (((char*) ptr) + WORD_LENGTH); +} + +void +operator delete (void* ptr) { + ptr = (void*) (((char*) ptr) - WORD_LENGTH); + size_t s= *((size_t*) ptr); + if (s < MAX_FAST) { + ind (ptr) = alloc_ptr (s); + alloc_ptr (s)= ptr; + } + else { + free (ptr); + large_uses-= s; + } +} + +void* +operator new[] (size_t s) { + void* ptr; + s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; + if (s < MAX_FAST) { + ptr= alloc_ptr (s); + if (ptr == NULL) ptr= enlarge_malloc (s); + else alloc_ptr (s)= ind (ptr); + } + else { + ptr= safe_malloc (s); + large_uses+= s; + } + *((size_t*) ptr)= s; + return (void*) (((char*) ptr) + WORD_LENGTH); +} + +void +operator delete[] (void* ptr) { + ptr = (void*) (((char*) ptr) - WORD_LENGTH); + size_t s= *((size_t*) ptr); + if (s < MAX_FAST) { + ind (ptr) = alloc_ptr (s); + alloc_ptr (s)= ptr; + } + else { + free (ptr); + large_uses-= s; + } +} + +#endif // defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) diff --git a/System/Memory/impl/mi_malloc.cpp b/System/Memory/impl/mi_malloc.cpp new file mode 100644 index 000000000..4a63721c0 --- /dev/null +++ b/System/Memory/impl/mi_malloc.cpp @@ -0,0 +1,159 @@ + +/****************************************************************************** + * MODULE : Fast memory allocation using mimalloc + * DESCRIPTION: + * COPYRIGHT : (C) 1999 Joris van der Hoeven + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +#include "fast_alloc.hpp" +#include "assert.h" +#include "mimalloc.h" + +int mem_used (); + +/*****************************************************************************/ +// General purpose fast allocation routines +/*****************************************************************************/ + +void* +safe_malloc (size_t sz) { + void* ptr= NULL; + if (sz < MI_SMALL_SIZE_MAX) + { + ptr = mi_malloc_small (sz); + }else{ + + ptr = mi_malloc (sz); + } + + if (ptr == NULL) { + cerr << "Fatal error: out of memory\n"; + abort (); + } + return ptr; +} + +void* +enlarge_malloc (size_t sz) { + return NULL; +} + +void* +fast_alloc (size_t sz) { + return safe_malloc (sz); +} + +void +fast_free (void* ptr, size_t sz) { + mi_free (ptr); +} + +void* +fast_new (size_t s) { + return safe_malloc (s); +} + +void +fast_delete (void* ptr) { + mi_free (ptr); +} + +/****************************************************************************** + * Statistics + ******************************************************************************/ + +bool +visit_mem (const mi_heap_t* heap, const mi_heap_area_t* heapinfo, void* block, + size_t blocksize, void* arg) { + int* count= (int*) arg; + assert(heapinfo != NULL); + *count+= heapinfo->used; + return true; +} + +int +mem_used () { + mi_heap_t* heap = mi_heap_get_default (); + int count= 0; + mi_heap_visit_blocks (heap, false, visit_mem, &count); + return count; +} + +void +mem_info () { + cout << "\n---------------- memory statistics ----------------\n"; +} + +/****************************************************************************** + * Redefine standard new and delete + ******************************************************************************/ + +#if defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) + +void* +operator new (size_t s) { + void* ptr; + s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; + if (s < MAX_FAST) { + ptr= alloc_ptr (s); + if (ptr == NULL) ptr= enlarge_malloc (s); + else alloc_ptr (s)= ind (ptr); + } + else { + ptr= safe_malloc (s); + large_uses+= s; + } + *((size_t*) ptr)= s; + return (void*) (((char*) ptr) + WORD_LENGTH); +} + +void +operator delete (void* ptr) { + ptr = (void*) (((char*) ptr) - WORD_LENGTH); + size_t s= *((size_t*) ptr); + if (s < MAX_FAST) { + ind (ptr) = alloc_ptr (s); + alloc_ptr (s)= ptr; + } + else { + free (ptr); + large_uses-= s; + } +} + +void* +operator new[] (size_t s) { + void* ptr; + s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; + if (s < MAX_FAST) { + ptr= alloc_ptr (s); + if (ptr == NULL) ptr= enlarge_malloc (s); + else alloc_ptr (s)= ind (ptr); + } + else { + ptr= safe_malloc (s); + large_uses+= s; + } + *((size_t*) ptr)= s; + return (void*) (((char*) ptr) + WORD_LENGTH); +} + +void +operator delete[] (void* ptr) { + ptr = (void*) (((char*) ptr) - WORD_LENGTH); + size_t s= *((size_t*) ptr); + if (s < MAX_FAST) { + ind (ptr) = alloc_ptr (s); + alloc_ptr (s)= ptr; + } + else { + free (ptr); + large_uses-= s; + } +} + +#endif // defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 8503ce540..42b23fb7f 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -1,5 +1,16 @@ #include "a_lolly_test.hpp" #include "fast_alloc.hpp" +#include "tm_timer.hpp" + +int +usec_diff (time_t start, time_t end) { + if (start <= end) { + return end - start; + } + else { + return end + 1000000 - start; + } +} struct Complex { public: @@ -40,6 +51,7 @@ TEST_CASE ("test basic data types") { int* in[NUM]; long* lo[NUM]; double* dou[NUM]; + int time= get_usec_time (); for (int i= 0; i < NUM; i++) { // for gprof ch[i]= tm_new (); @@ -68,6 +80,7 @@ TEST_CASE ("test basic data types") { tm_delete (lo[i]); tm_delete (dou[i]); } + cout << "basic type: " << usec_diff(time, get_usec_time ()) << LF; } TEST_CASE ("test class") { @@ -83,10 +96,12 @@ TEST_CASE ("test tm_*_array") { #else const size_t size_prim= 20000000, size_complex= 5000000; #endif + int time = get_usec_time (); p_complex= tm_new_array (size_prim); tm_delete_array (p_complex); Complex* p_wide= tm_new_array (size_complex); tm_delete_array (p_wide); + cout << "large array: " << usec_diff(time, get_usec_time ()) << LF; } #ifndef OS_WASM @@ -106,12 +121,23 @@ TEST_MEMORY_LEAK_RESET TEST_CASE ("test large bunch of tm_*_array with class") { Complex* volume[NUM]; + int time= get_usec_time (); for (int i= 0; i < NUM; i++) { volume[i]= tm_new_array (9); } for (int i= 0; i < NUM; i++) { tm_delete_array (volume[i]); } + cout << "frequent allocation of array: " << usec_diff(time, get_usec_time ()) << LF; + time = get_usec_time(); + for (int i= 0; i < NUM; i++) { + volume[i]= tm_new_array (9); + } + for (int i= 0; i < NUM; i++) { + tm_delete_array (volume[i]); + } + cout << "frequent allocation by reuse: " << usec_diff(time, get_usec_time ()) << LF; + } TEST_MEMORY_LEAK_ALL diff --git a/xmake.lua b/xmake.lua index 563582c74..aa29f0571 100644 --- a/xmake.lua +++ b/xmake.lua @@ -74,7 +74,7 @@ end local lolly_files = { "Kernel/**/*.cpp", - "System/**/*.cpp", + "System/**/*.cpp|Memory/impl/*.cpp", "Data/String/**.cpp", "Data/Scheme/**.cpp", "lolly/**/**.cpp", @@ -107,12 +107,14 @@ target("liblolly") do --- dependent packages add_packages("tbox") - if is_config("malloc", "mimalloc") then - add_defines("MIMALLOC") + if is_config("malloc", "mimalloc") then add_packages("mimalloc") + add_files("System/Memory/impl/mi_malloc.cpp") elseif is_config("malloc", "jemalloc") then - add_defines("JEMALLOC") add_packages("jemalloc") + add_files("System/Memory/impl/je_malloc.cpp") + else + add_files("System/Memory/impl/fast_alloc.cpp") end if not is_plat("wasm") then add_packages("cpr") From 243e8de3d274efb304edb10c6deb39c57d5bd4d2 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 09:45:11 +0800 Subject: [PATCH 09/17] fix bug for test of mimalloc --- System/Memory/impl/mi_malloc.cpp | 89 ++----------------------- tests/System/Memory/fast_alloc_test.cpp | 2 +- 2 files changed, 6 insertions(+), 85 deletions(-) diff --git a/System/Memory/impl/mi_malloc.cpp b/System/Memory/impl/mi_malloc.cpp index 4a63721c0..b21112ac5 100644 --- a/System/Memory/impl/mi_malloc.cpp +++ b/System/Memory/impl/mi_malloc.cpp @@ -2,34 +2,25 @@ /****************************************************************************** * MODULE : Fast memory allocation using mimalloc * DESCRIPTION: - * COPYRIGHT : (C) 1999 Joris van der Hoeven + * COPYRIGHT : (C) 2023-2024 jingkaimori ******************************************************************************* * This software falls under the GNU general public license version 3 or later. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE * in the root directory or . ******************************************************************************/ -#include "fast_alloc.hpp" #include "assert.h" +#include "basic.hpp" +#include "fast_alloc.hpp" #include "mimalloc.h" -int mem_used (); - /*****************************************************************************/ // General purpose fast allocation routines /*****************************************************************************/ void* safe_malloc (size_t sz) { - void* ptr= NULL; - if (sz < MI_SMALL_SIZE_MAX) - { - ptr = mi_malloc_small (sz); - }else{ - - ptr = mi_malloc (sz); - } - + void* ptr= mi_malloc (mi_good_size (sz)); if (ptr == NULL) { cerr << "Fatal error: out of memory\n"; abort (); @@ -70,7 +61,6 @@ bool visit_mem (const mi_heap_t* heap, const mi_heap_area_t* heapinfo, void* block, size_t blocksize, void* arg) { int* count= (int*) arg; - assert(heapinfo != NULL); *count+= heapinfo->used; return true; } @@ -86,74 +76,5 @@ mem_used () { void mem_info () { cout << "\n---------------- memory statistics ----------------\n"; + cout << "malloc overrided:" << mi_is_redirected () << "\n"; } - -/****************************************************************************** - * Redefine standard new and delete - ******************************************************************************/ - -#if defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) - -void* -operator new (size_t s) { - void* ptr; - s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; - if (s < MAX_FAST) { - ptr= alloc_ptr (s); - if (ptr == NULL) ptr= enlarge_malloc (s); - else alloc_ptr (s)= ind (ptr); - } - else { - ptr= safe_malloc (s); - large_uses+= s; - } - *((size_t*) ptr)= s; - return (void*) (((char*) ptr) + WORD_LENGTH); -} - -void -operator delete (void* ptr) { - ptr = (void*) (((char*) ptr) - WORD_LENGTH); - size_t s= *((size_t*) ptr); - if (s < MAX_FAST) { - ind (ptr) = alloc_ptr (s); - alloc_ptr (s)= ptr; - } - else { - free (ptr); - large_uses-= s; - } -} - -void* -operator new[] (size_t s) { - void* ptr; - s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; - if (s < MAX_FAST) { - ptr= alloc_ptr (s); - if (ptr == NULL) ptr= enlarge_malloc (s); - else alloc_ptr (s)= ind (ptr); - } - else { - ptr= safe_malloc (s); - large_uses+= s; - } - *((size_t*) ptr)= s; - return (void*) (((char*) ptr) + WORD_LENGTH); -} - -void -operator delete[] (void* ptr) { - ptr = (void*) (((char*) ptr) - WORD_LENGTH); - size_t s= *((size_t*) ptr); - if (s < MAX_FAST) { - ind (ptr) = alloc_ptr (s); - alloc_ptr (s)= ptr; - } - else { - free (ptr); - large_uses-= s; - } -} - -#endif // defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index 42b23fb7f..a2f09494a 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -34,7 +34,7 @@ TEST_CASE ("test for memory leaks") { char* q_char= tm_new ('z'); // here p_char is modified to 'z' - *p_char= 'c'; // here q_char is modified to 'c' + // *p_char= 'c'; // behavior of this code is unspecified, DO NOT DO THIS! } TEST_MEMORY_LEAK_INIT From a933eab8b594b27339284e3c6b89a702c690c74e Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 09:54:42 +0800 Subject: [PATCH 10/17] refactor to hide implementation from interface --- System/Memory/fast_alloc.hpp | 23 +---------------------- System/Memory/impl/fast_alloc.cpp | 11 ++++++++++- System/Memory/impl/je_malloc.cpp | 10 +++++----- System/Memory/impl/mi_malloc.cpp | 5 ----- 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/System/Memory/fast_alloc.hpp b/System/Memory/fast_alloc.hpp index 41f46d446..a1ddb14ed 100644 --- a/System/Memory/fast_alloc.hpp +++ b/System/Memory/fast_alloc.hpp @@ -12,8 +12,8 @@ #ifndef FAST_ALLOC_H #define FAST_ALLOC_H -#include #include "tm_ostream.hpp" +#include #define WORD_LENGTH 8 #define WORD_LENGTH_INC 7 #define WORD_MASK 0xfffffffffffffff8 @@ -21,31 +21,10 @@ #define MAX_FAST 264 #define BLOCK_SIZE 65536 // should be >>> MAX_FAST -/****************************************************************************** - * Globals - ******************************************************************************/ - -extern void* - alloc_table[MAX_FAST]; // Static declaration initializes with NULL's -extern char* alloc_mem; -#ifdef DEBUG_ON -extern char* alloc_mem_top; -extern char* alloc_mem_bottom; -#endif -bool break_stub (void* ptr); -extern size_t alloc_remains; -extern int allocated; -extern int large_uses; - -#define alloc_ptr(i) alloc_table[i] -#define ind(ptr) (*((void**) ptr)) - /****************************************************************************** * General purpose fast allocation routines ******************************************************************************/ -extern void* safe_malloc (size_t s); -extern void* enlarge_malloc (size_t s); extern void* fast_alloc (size_t s); extern void fast_free (void* ptr, size_t s); extern void* fast_new (size_t s); diff --git a/System/Memory/impl/fast_alloc.cpp b/System/Memory/impl/fast_alloc.cpp index bd875c896..4ca277f4f 100644 --- a/System/Memory/impl/fast_alloc.cpp +++ b/System/Memory/impl/fast_alloc.cpp @@ -16,6 +16,10 @@ #include "fast_alloc.hpp" +/****************************************************************************** + * Globals + ******************************************************************************/ + void* alloc_table[MAX_FAST]; // Static declaration initializes with NULL's char* alloc_mem= NULL; #ifdef DEBUG_ON @@ -27,12 +31,17 @@ int allocated = 0; int fast_chunks = 0; int large_uses = 0; int MEM_DEBUG = 0; -int mem_used (); /*****************************************************************************/ // General purpose fast allocation routines /*****************************************************************************/ +#define alloc_ptr(i) alloc_table[i] +#define ind(ptr) (*((void**) ptr)) + +bool break_stub (void* ptr); +int mem_used (); + void* safe_malloc (size_t sz) { void* ptr= malloc (sz); diff --git a/System/Memory/impl/je_malloc.cpp b/System/Memory/impl/je_malloc.cpp index 05b498902..f94ce3b01 100644 --- a/System/Memory/impl/je_malloc.cpp +++ b/System/Memory/impl/je_malloc.cpp @@ -30,11 +30,6 @@ safe_malloc (size_t sz) { return ptr; } -void* -enlarge_malloc (size_t sz) { - return NULL; -} - void* fast_alloc (size_t sz) { return safe_malloc (sz); @@ -75,6 +70,11 @@ mem_info () { #if defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) +void* +enlarge_malloc (size_t sz) { + return NULL; +} + void* operator new (size_t s) { void* ptr; diff --git a/System/Memory/impl/mi_malloc.cpp b/System/Memory/impl/mi_malloc.cpp index b21112ac5..ad5e73811 100644 --- a/System/Memory/impl/mi_malloc.cpp +++ b/System/Memory/impl/mi_malloc.cpp @@ -28,11 +28,6 @@ safe_malloc (size_t sz) { return ptr; } -void* -enlarge_malloc (size_t sz) { - return NULL; -} - void* fast_alloc (size_t sz) { return safe_malloc (sz); From 38be421d9832ecec86171126e2b6c4470519b9f3 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 10:18:57 +0800 Subject: [PATCH 11/17] enable ci for mimalloc --- .github/workflows/ci-xmake-linux.yml | 6 +++++- .github/workflows/ci-xmake-macos.yml | 6 +++++- .github/workflows/ci-xmake-windows.yml | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-xmake-linux.yml b/.github/workflows/ci-xmake-linux.yml index cfd6ccb54..4169f76f7 100644 --- a/.github/workflows/ci-xmake-linux.yml +++ b/.github/workflows/ci-xmake-linux.yml @@ -24,6 +24,10 @@ on: jobs: linuxbuild: runs-on: ubuntu-22.04 + strategy: + matrix: + malloc: + [mimalloc, standard] steps: - name: Install dependencies run: | @@ -50,7 +54,7 @@ jobs: key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }} # Force xmake to a specific folder (for cache) - name: config - run: xmake config --yes -vD + run: xmake config --yes -vD --malloc={{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test diff --git a/.github/workflows/ci-xmake-macos.yml b/.github/workflows/ci-xmake-macos.yml index 8e75624f7..e1e9ced44 100644 --- a/.github/workflows/ci-xmake-macos.yml +++ b/.github/workflows/ci-xmake-macos.yml @@ -23,6 +23,10 @@ on: jobs: macosbuild: runs-on: macos-11 + strategy: + matrix: + malloc: + [mimalloc, standard] steps: - uses: actions/checkout@v2 with: @@ -55,7 +59,7 @@ jobs: key: ${{ runner.os }}-xmake-qt${{ matrix.qt_ver }}-${{ hashFiles('**/xmake.lua') }} - name: config - run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD + run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD --malloc={{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test diff --git a/.github/workflows/ci-xmake-windows.yml b/.github/workflows/ci-xmake-windows.yml index 511053f2e..6b5320454 100644 --- a/.github/workflows/ci-xmake-windows.yml +++ b/.github/workflows/ci-xmake-windows.yml @@ -24,6 +24,10 @@ on: jobs: windowsbuild: runs-on: windows-2019 + strategy: + matrix: + malloc: + [mimalloc, standard] env: # Force xmake to a specific folder (for cache) XMAKE_GLOBALDIR: ${{ github.workspace }}/.xmake-global @@ -46,7 +50,7 @@ jobs: ${{ github.workspace }}/build/.build_cache key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }} - name: config - run: xmake config --yes -vD + run: xmake config --yes -vD --malloc={{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test From 5b489fc6f6301fff7a1e0e03e83c7d918c5a4913 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 10:53:04 +0800 Subject: [PATCH 12/17] fix ci --- .github/workflows/ci-xmake-linux.yml | 2 +- .github/workflows/ci-xmake-macos.yml | 2 +- .github/workflows/ci-xmake-windows.yml | 2 +- System/Memory/impl/je_malloc.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-xmake-linux.yml b/.github/workflows/ci-xmake-linux.yml index 4169f76f7..a7910ef59 100644 --- a/.github/workflows/ci-xmake-linux.yml +++ b/.github/workflows/ci-xmake-linux.yml @@ -54,7 +54,7 @@ jobs: key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }} # Force xmake to a specific folder (for cache) - name: config - run: xmake config --yes -vD --malloc={{ matrix.malloc }} + run: xmake config --yes -vD --malloc=${{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test diff --git a/.github/workflows/ci-xmake-macos.yml b/.github/workflows/ci-xmake-macos.yml index e1e9ced44..e3d92e59b 100644 --- a/.github/workflows/ci-xmake-macos.yml +++ b/.github/workflows/ci-xmake-macos.yml @@ -59,7 +59,7 @@ jobs: key: ${{ runner.os }}-xmake-qt${{ matrix.qt_ver }}-${{ hashFiles('**/xmake.lua') }} - name: config - run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD --malloc={{ matrix.malloc }} + run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD --malloc=${{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test diff --git a/.github/workflows/ci-xmake-windows.yml b/.github/workflows/ci-xmake-windows.yml index 6b5320454..a3a0757a5 100644 --- a/.github/workflows/ci-xmake-windows.yml +++ b/.github/workflows/ci-xmake-windows.yml @@ -50,7 +50,7 @@ jobs: ${{ github.workspace }}/build/.build_cache key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }} - name: config - run: xmake config --yes -vD --malloc={{ matrix.malloc }} + run: xmake config --yes -vD --malloc=${{ matrix.malloc }} - name: build run: xmake build --yes -vD - name: test diff --git a/System/Memory/impl/je_malloc.cpp b/System/Memory/impl/je_malloc.cpp index f94ce3b01..14926b801 100644 --- a/System/Memory/impl/je_malloc.cpp +++ b/System/Memory/impl/je_malloc.cpp @@ -9,8 +9,8 @@ * in the root directory or . ******************************************************************************/ -#include "fast_alloc.hpp" #include "assert.h" +#include "fast_alloc.hpp" #include "jemalloc/jemalloc.h" int mem_used (); @@ -22,7 +22,7 @@ int mem_used (); void* safe_malloc (size_t sz) { void* ptr= malloc (sz); - + if (ptr == NULL) { cerr << "Fatal error: out of memory\n"; abort (); From c84236fbfa8957857862d25a8bd6ed388eb9cccf Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 11:02:04 +0800 Subject: [PATCH 13/17] fix lint error --- tests/System/Memory/fast_alloc_test.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/System/Memory/fast_alloc_test.cpp b/tests/System/Memory/fast_alloc_test.cpp index a2f09494a..88fe68849 100644 --- a/tests/System/Memory/fast_alloc_test.cpp +++ b/tests/System/Memory/fast_alloc_test.cpp @@ -80,7 +80,7 @@ TEST_CASE ("test basic data types") { tm_delete (lo[i]); tm_delete (dou[i]); } - cout << "basic type: " << usec_diff(time, get_usec_time ()) << LF; + cout << "basic type: " << usec_diff (time, get_usec_time ()) << LF; } TEST_CASE ("test class") { @@ -101,7 +101,7 @@ TEST_CASE ("test tm_*_array") { tm_delete_array (p_complex); Complex* p_wide= tm_new_array (size_complex); tm_delete_array (p_wide); - cout << "large array: " << usec_diff(time, get_usec_time ()) << LF; + cout << "large array: " << usec_diff (time, get_usec_time ()) << LF; } #ifndef OS_WASM @@ -128,16 +128,17 @@ TEST_CASE ("test large bunch of tm_*_array with class") { for (int i= 0; i < NUM; i++) { tm_delete_array (volume[i]); } - cout << "frequent allocation of array: " << usec_diff(time, get_usec_time ()) << LF; - time = get_usec_time(); + cout << "frequent allocation of array: " << usec_diff (time, get_usec_time ()) + << LF; + time= get_usec_time (); for (int i= 0; i < NUM; i++) { volume[i]= tm_new_array (9); } for (int i= 0; i < NUM; i++) { tm_delete_array (volume[i]); } - cout << "frequent allocation by reuse: " << usec_diff(time, get_usec_time ()) << LF; - + cout << "frequent allocation by reuse: " << usec_diff (time, get_usec_time ()) + << LF; } TEST_MEMORY_LEAK_ALL From 1dd18d38367e35d92aa8804749a28f36f99921b6 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 14:06:14 +0800 Subject: [PATCH 14/17] enable jemalloc on linux and macos --- .github/workflows/ci-xmake-linux.yml | 2 +- .github/workflows/ci-xmake-macos.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-xmake-linux.yml b/.github/workflows/ci-xmake-linux.yml index a7910ef59..594927c78 100644 --- a/.github/workflows/ci-xmake-linux.yml +++ b/.github/workflows/ci-xmake-linux.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: malloc: - [mimalloc, standard] + [mimalloc, jemalloc, standard] steps: - name: Install dependencies run: | diff --git a/.github/workflows/ci-xmake-macos.yml b/.github/workflows/ci-xmake-macos.yml index e3d92e59b..1a05b277b 100644 --- a/.github/workflows/ci-xmake-macos.yml +++ b/.github/workflows/ci-xmake-macos.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: malloc: - [mimalloc, standard] + [mimalloc, jemalloc, standard] steps: - uses: actions/checkout@v2 with: From bef32a2f0dc84b9cb1de8e460e0353e589731562 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 16:46:40 +0800 Subject: [PATCH 15/17] rename option and update author information --- .github/workflows/ci-xmake-linux.yml | 2 +- .github/workflows/ci-xmake-macos.yml | 2 +- .github/workflows/ci-xmake-windows.yml | 2 +- System/Memory/impl/je_malloc.cpp | 2 +- xmake.lua | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-xmake-linux.yml b/.github/workflows/ci-xmake-linux.yml index 594927c78..80178c7eb 100644 --- a/.github/workflows/ci-xmake-linux.yml +++ b/.github/workflows/ci-xmake-linux.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: malloc: - [mimalloc, jemalloc, standard] + [mimalloc, jemalloc, default] steps: - name: Install dependencies run: | diff --git a/.github/workflows/ci-xmake-macos.yml b/.github/workflows/ci-xmake-macos.yml index 1a05b277b..2f2ae540d 100644 --- a/.github/workflows/ci-xmake-macos.yml +++ b/.github/workflows/ci-xmake-macos.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: malloc: - [mimalloc, jemalloc, standard] + [mimalloc, default] steps: - uses: actions/checkout@v2 with: diff --git a/.github/workflows/ci-xmake-windows.yml b/.github/workflows/ci-xmake-windows.yml index a3a0757a5..1345ac326 100644 --- a/.github/workflows/ci-xmake-windows.yml +++ b/.github/workflows/ci-xmake-windows.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: malloc: - [mimalloc, standard] + [mimalloc, default] env: # Force xmake to a specific folder (for cache) XMAKE_GLOBALDIR: ${{ github.workspace }}/.xmake-global diff --git a/System/Memory/impl/je_malloc.cpp b/System/Memory/impl/je_malloc.cpp index 14926b801..29b21b462 100644 --- a/System/Memory/impl/je_malloc.cpp +++ b/System/Memory/impl/je_malloc.cpp @@ -2,7 +2,7 @@ /****************************************************************************** * MODULE : Fast memory allocation using mimalloc * DESCRIPTION: - * COPYRIGHT : (C) 1999 Joris van der Hoeven + * COPYRIGHT : (C) 2023-2024 jingkaimori ******************************************************************************* * This software falls under the GNU general public license version 3 or later. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE diff --git a/xmake.lua b/xmake.lua index aa29f0571..c8a6b4356 100644 --- a/xmake.lua +++ b/xmake.lua @@ -29,10 +29,10 @@ tbox_configs = {hash=true, ["force-utf8"]=true, charset=true} add_requires("tbox 1.7.5", {system=false, configs=tbox_configs}) add_requires("doctest 2.4.11", {system=false}) option("malloc") - set_default("standard") + set_default("default") set_showmenu(true) set_description("Enable mimalloc or jemalloc library") - set_values("standard", "mimalloc", "jemalloc") + set_values("default", "mimalloc", "jemalloc") option_end() if is_config("malloc", "mimalloc") then add_requires("mimalloc 2.1.2") From afb3e4ae7f0cfb7e012a13784f89763e0a6bf335 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 17:05:15 +0800 Subject: [PATCH 16/17] code cleanup --- System/Memory/impl/je_malloc.cpp | 82 ++------------------------------ System/Memory/impl/mi_malloc.cpp | 2 +- 2 files changed, 5 insertions(+), 79 deletions(-) diff --git a/System/Memory/impl/je_malloc.cpp b/System/Memory/impl/je_malloc.cpp index 29b21b462..6e06c2f4f 100644 --- a/System/Memory/impl/je_malloc.cpp +++ b/System/Memory/impl/je_malloc.cpp @@ -1,6 +1,6 @@ /****************************************************************************** - * MODULE : Fast memory allocation using mimalloc + * MODULE : Fast memory allocation using jemalloc * DESCRIPTION: * COPYRIGHT : (C) 2023-2024 jingkaimori ******************************************************************************* @@ -11,7 +11,7 @@ #include "assert.h" #include "fast_alloc.hpp" -#include "jemalloc/jemalloc.h" +#include int mem_used (); @@ -56,85 +56,11 @@ fast_delete (void* ptr) { int mem_used () { + cerr << "memory statistics is NOT IMPLEMENTED\n"; return 0; } void mem_info () { - cout << "\n---------------- memory statistics ----------------\n"; + cout << "\n------- (NOT IMPLEMENTED) memory statistics -------\n"; } - -/****************************************************************************** - * Redefine standard new and delete - ******************************************************************************/ - -#if defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) - -void* -enlarge_malloc (size_t sz) { - return NULL; -} - -void* -operator new (size_t s) { - void* ptr; - s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; - if (s < MAX_FAST) { - ptr= alloc_ptr (s); - if (ptr == NULL) ptr= enlarge_malloc (s); - else alloc_ptr (s)= ind (ptr); - } - else { - ptr= safe_malloc (s); - large_uses+= s; - } - *((size_t*) ptr)= s; - return (void*) (((char*) ptr) + WORD_LENGTH); -} - -void -operator delete (void* ptr) { - ptr = (void*) (((char*) ptr) - WORD_LENGTH); - size_t s= *((size_t*) ptr); - if (s < MAX_FAST) { - ind (ptr) = alloc_ptr (s); - alloc_ptr (s)= ptr; - } - else { - free (ptr); - large_uses-= s; - } -} - -void* -operator new[] (size_t s) { - void* ptr; - s= (s + WORD_LENGTH + WORD_LENGTH_INC) & WORD_MASK; - if (s < MAX_FAST) { - ptr= alloc_ptr (s); - if (ptr == NULL) ptr= enlarge_malloc (s); - else alloc_ptr (s)= ind (ptr); - } - else { - ptr= safe_malloc (s); - large_uses+= s; - } - *((size_t*) ptr)= s; - return (void*) (((char*) ptr) + WORD_LENGTH); -} - -void -operator delete[] (void* ptr) { - ptr = (void*) (((char*) ptr) - WORD_LENGTH); - size_t s= *((size_t*) ptr); - if (s < MAX_FAST) { - ind (ptr) = alloc_ptr (s); - alloc_ptr (s)= ptr; - } - else { - free (ptr); - large_uses-= s; - } -} - -#endif // defined(X11TEXMACS) && (!defined(NO_FAST_ALLOC)) diff --git a/System/Memory/impl/mi_malloc.cpp b/System/Memory/impl/mi_malloc.cpp index ad5e73811..8fea9f525 100644 --- a/System/Memory/impl/mi_malloc.cpp +++ b/System/Memory/impl/mi_malloc.cpp @@ -12,7 +12,7 @@ #include "assert.h" #include "basic.hpp" #include "fast_alloc.hpp" -#include "mimalloc.h" +#include /*****************************************************************************/ // General purpose fast allocation routines From 2b9b052f23efa7f4444db71029a9dc54b3ccf4a5 Mon Sep 17 00:00:00 2001 From: jingkaimori Date: Sun, 14 Jan 2024 17:28:07 +0800 Subject: [PATCH 17/17] add description of options --- xmake.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/xmake.lua b/xmake.lua index c8a6b4356..8c2a071d9 100644 --- a/xmake.lua +++ b/xmake.lua @@ -31,8 +31,19 @@ add_requires("doctest 2.4.11", {system=false}) option("malloc") set_default("default") set_showmenu(true) - set_description("Enable mimalloc or jemalloc library") - set_values("default", "mimalloc", "jemalloc") + set_description([[ +Enable mimalloc or jemalloc library. + - default + - mimalloc (on windows, linux, and macos) + - jemalloc (on linux) +]]) + if is_plat("linux") then + set_values("default", "mimalloc", "jemalloc") + elseif is_plat("wasm") then + set_values("default") + else + set_values("default", "mimalloc") + end option_end() if is_config("malloc", "mimalloc") then add_requires("mimalloc 2.1.2")