diff --git a/ide/vs2022/mimalloc.vcxproj b/ide/vs2022/mimalloc.vcxproj index 87e866bb..2c4477d9 100644 --- a/ide/vs2022/mimalloc.vcxproj +++ b/ide/vs2022/mimalloc.vcxproj @@ -190,7 +190,7 @@ true Default ../../include - MI_DEBUG=3;MI_GUARDED=0;%(PreprocessorDefinitions); + MI_DEBUG=3;MI_SECURE=4;%(PreprocessorDefinitions); CompileAsCpp false stdcpp20 diff --git a/include/mimalloc.h b/include/mimalloc.h index b0a20e9e..8bff8923 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -398,8 +398,8 @@ typedef enum mi_option_e { mi_option_reclaim_on_free, // allow to reclaim an abandoned segment on a free (=1) mi_option_full_page_retain, // retain N full pages per size class (=2) mi_option_max_page_candidates, // max candidate pages to consider for allocation (=4) - mi_option_max_vabits, // max virtual address bits to consider in user space (=48) - mi_option_debug_commit_full_pagemap, // commit the full pagemap to catch invalid pointer uses (=0) + mi_option_max_vabits, // max user space virtual address bits to consider (=48) + mi_option_pagemap_commit, // commit the full pagemap (to always catch invalid pointer uses) (=0) _mi_option_last, // legacy option names mi_option_large_os_pages = mi_option_allow_large_os_pages, diff --git a/include/mimalloc/bits.h b/include/mimalloc/bits.h index ed4a7b44..875f6230 100644 --- a/include/mimalloc/bits.h +++ b/include/mimalloc/bits.h @@ -120,7 +120,7 @@ typedef int32_t mi_ssize_t; // use a flat page-map (or a 2-level one) #ifndef MI_PAGE_MAP_FLAT -#if MI_MAX_VABITS <= 40 +#if MI_MAX_VABITS <= 40 && !defined(__APPLE__) #define MI_PAGE_MAP_FLAT 1 #else #define MI_PAGE_MAP_FLAT 0 diff --git a/include/mimalloc/internal.h b/include/mimalloc/internal.h index 5dc2074d..9146896c 100644 --- a/include/mimalloc/internal.h +++ b/include/mimalloc/internal.h @@ -445,6 +445,7 @@ static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t si #if MI_PAGE_MAP_FLAT // flat page-map committed on demand +// single indirection and low commit, but large initial virtual reserve (4 GiB with 48 bit virtual addresses) extern uint8_t* _mi_page_map; static inline size_t _mi_page_map_index(const void* p) { @@ -471,6 +472,8 @@ static inline mi_page_t* _mi_unchecked_ptr_page(const void* p) { #else // 2-level page map: +// double indirection but low commit and low virtual reserve. +// // The page-map is usually 4 MiB and points to sub maps of 64 KiB. // The page-map is committed on-demand (in 64 KiB) parts (and sub-maps are committed on-demand as well) // One sub page-map = 64 KiB => covers 2^13 * 2^16 = 2^32 = 512 MiB address space diff --git a/src/alloc.c b/src/alloc.c index e5f2b8ae..6b037987 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -674,7 +674,7 @@ mi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, boo #if MI_STAT>1 mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); #endif - _mi_stat_counter_increase(&heap->tld->stats.guarded_alloc_count, 1); + mi_heap_stat_counter_increase(heap, guarded_alloc_count, 1); } #if MI_DEBUG>3 if (p != NULL && zero) { diff --git a/src/options.c b/src/options.c index 4f1a00b8..fc3a2838 100644 --- a/src/options.c +++ b/src/options.c @@ -102,6 +102,14 @@ typedef struct mi_option_desc_s { #endif #endif +#ifndef MI_DEFAULT_PAGEMAP_COMMIT +#if defined(__APPLE__) +#define MI_DEFAULT_PAGEMAP_COMMIT 1 +#else +#define MI_DEFAULT_PAGEMAP_COMMIT 0 +#endif +#endif + static mi_option_desc_t options[_mi_option_last] = { @@ -165,7 +173,8 @@ static mi_option_desc_t options[_mi_option_last] = { 2, UNINIT, MI_OPTION(full_page_retain) }, { 4, UNINIT, MI_OPTION(max_page_candidates) }, { 0, UNINIT, MI_OPTION(max_vabits) }, - { 0, UNINIT, MI_OPTION(debug_commit_full_pagemap) }, + { MI_DEFAULT_PAGEMAP_COMMIT, + UNINIT, MI_OPTION(pagemap_commit) }, // commit the full pagemap upfront? }; static void mi_option_init(mi_option_desc_t* desc); diff --git a/src/page-map.c b/src/page-map.c index 190be6c0..37ce3082 100644 --- a/src/page-map.c +++ b/src/page-map.c @@ -42,7 +42,7 @@ bool _mi_page_map_init(void) { // Allocate the page map and commit bits mi_page_map_max_address = (void*)(MI_PU(1) << vbits); const size_t page_map_size = (MI_ZU(1) << (vbits - MI_ARENA_SLICE_SHIFT)); - const bool commit = (page_map_size <= 1*MI_MiB || mi_option_is_enabled(mi_option_debug_commit_full_pagemap)); // _mi_os_has_overcommit(); // commit on-access on Linux systems? + const bool commit = (page_map_size <= 1*MI_MiB || mi_option_is_enabled(mi_option_pagemap_commit)); // _mi_os_has_overcommit(); // commit on-access on Linux systems? const size_t commit_bits = _mi_divide_up(page_map_size, MI_PAGE_MAP_ENTRIES_PER_COMMIT_BIT); const size_t bitmap_size = (commit ? 0 : mi_bitmap_size(commit_bits, NULL)); const size_t reserve_size = bitmap_size + page_map_size; @@ -187,7 +187,7 @@ bool _mi_page_map_init(void) { const size_t os_page_size = _mi_os_page_size(); const size_t page_map_size = _mi_align_up( page_map_count * sizeof(mi_page_t**), os_page_size); const size_t reserve_size = page_map_size + os_page_size; - const bool commit = page_map_size <= 64*MI_KiB || mi_option_is_enabled(mi_option_debug_commit_full_pagemap); // _mi_os_has_overcommit(); // commit on-access on Linux systems? + const bool commit = page_map_size <= 64*MI_KiB || mi_option_is_enabled(mi_option_pagemap_commit); // _mi_os_has_overcommit(); // commit on-access on Linux systems? _mi_page_map = (mi_page_t***)_mi_os_alloc_aligned(reserve_size, 1, commit, true /* allow large */, &mi_page_map_memid); if (_mi_page_map==NULL) { _mi_error_message(ENOMEM, "unable to reserve virtual memory for the page map (%zu KiB)\n", page_map_size / MI_KiB); diff --git a/test/main-override-static.c b/test/main-override-static.c index 410764bd..b16864db 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -35,7 +35,7 @@ int main() { // corrupt_free(); // block_overflow1(); // block_overflow2(); - // test_canary_leak(); + test_canary_leak(); // test_aslr(); // invalid_free(); // test_reserved();