From 79487dbedfb5de03b7b2da138d07bab213e9f7c9 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 20 Aug 2019 06:58:51 -0700 Subject: [PATCH 1/4] add checks for right option order --- include/mimalloc.h | 2 +- src/options.c | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/mimalloc.h b/include/mimalloc.h index c6b7b5f8..d14238a9 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -220,8 +220,8 @@ mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; typedef enum mi_option_e { // stable options - mi_option_show_stats, mi_option_show_errors, + mi_option_show_stats, mi_option_verbose, // the following options are experimental mi_option_secure, diff --git a/src/options.c b/src/options.c index cd7e5da1..f6059ae5 100644 --- a/src/options.c +++ b/src/options.c @@ -34,34 +34,38 @@ typedef enum mi_init_e { typedef struct mi_option_desc_s { long value; // the value mi_init_t init; // is it initialized yet? (from the environment) + mi_option_t option; // for debugging: the option index should match the option const char* name; // option name without `mimalloc_` prefix } mi_option_desc_t; +#define MI_OPTION(opt) mi_option_##opt, #opt +#define MI_OPTION_DESC(opt) {0, UNINIT, MI_OPTION(opt) } + static mi_option_desc_t options[_mi_option_last] = { // stable options - { 0, UNINIT, "show_stats" }, - { MI_DEBUG, UNINIT, "show_errors" }, - { 0, UNINIT, "verbose" }, + { MI_DEBUG, UNINIT, MI_OPTION(show_errors) }, + { 0, UNINIT, MI_OPTION(show_stats) }, + { 0, UNINIT, MI_OPTION(verbose) }, #if MI_SECURE - { MI_SECURE, INITIALIZED, "secure" }, // in a secure build the environment setting is ignored + { MI_SECURE, INITIALIZED, MI_OPTION(secure) }, // in a secure build the environment setting is ignored #else - { 0, UNINIT, "secure" }, + { 0, UNINIT, MI_OPTION(secure) }, #endif // the following options are experimental and not all combinations make sense. - { 1, UNINIT, "eager_commit" }, // note: if eager_region_commit is on, this should be on too. + { 1, UNINIT, MI_OPTION(eager_commit) }, // note: if eager_region_commit is on, this should be on too. #ifdef _WIN32 // and BSD? - { 0, UNINIT, "eager_region_commit" }, // don't commit too eagerly on windows (just for looks...) + { 0, UNINIT, MI_OPTION(eager_region_commit) }, // don't commit too eagerly on windows (just for looks...) #else - { 1, UNINIT, "eager_region_commit" }, + { 1, UNINIT, MI_OPTION(eager_region_commit) }, #endif - { 0, UNINIT, "large_os_pages" }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's - { 0, UNINIT, "page_reset" }, - { 0, UNINIT, "cache_reset" }, - { 0, UNINIT, "reset_decommits" }, // note: cannot enable this if secure is on - { 0, UNINIT, "reset_discards" } // note: cannot enable this if secure is on + { 0, UNINIT, MI_OPTION(large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's + { 0, UNINIT, MI_OPTION(page_reset) }, + { 0, UNINIT, MI_OPTION(cache_reset) }, + { 0, UNINIT, MI_OPTION(reset_decommits) }, // note: cannot enable this if secure is on + { 0, UNINIT, MI_OPTION(reset_discards) } // note: cannot enable this if secure is on }; static void mi_option_init(mi_option_desc_t* desc); @@ -69,6 +73,7 @@ static void mi_option_init(mi_option_desc_t* desc); long mi_option_get(mi_option_t option) { mi_assert(option >= 0 && option < _mi_option_last); mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option if (mi_unlikely(desc->init == UNINIT)) { mi_option_init(desc); if (option != mi_option_verbose) { @@ -81,6 +86,7 @@ long mi_option_get(mi_option_t option) { void mi_option_set(mi_option_t option, long value) { mi_assert(option >= 0 && option < _mi_option_last); mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option desc->value = value; desc->init = INITIALIZED; } From 598233135c8bddb14ecc76f75d15a32dbc6e13c4 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 20 Aug 2019 07:04:00 -0700 Subject: [PATCH 2/4] fix optimization settings on Windows compilation --- ide/vs2017/mimalloc-override.vcxproj | 4 ++-- ide/vs2017/mimalloc.vcxproj | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/ide/vs2017/mimalloc-override.vcxproj b/ide/vs2017/mimalloc-override.vcxproj index 7d452b55..8a7f8463 100644 --- a/ide/vs2017/mimalloc-override.vcxproj +++ b/ide/vs2017/mimalloc-override.vcxproj @@ -146,7 +146,6 @@ MaxSpeed true true - true true ../../include MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG @@ -155,6 +154,7 @@ false MultiThreadedDLL Default + false true @@ -173,7 +173,6 @@ MaxSpeed true true - true true ../../include MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG @@ -182,6 +181,7 @@ false MultiThreadedDLL Default + false true diff --git a/ide/vs2017/mimalloc.vcxproj b/ide/vs2017/mimalloc.vcxproj index 3e453471..854bf921 100644 --- a/ide/vs2017/mimalloc.vcxproj +++ b/ide/vs2017/mimalloc.vcxproj @@ -141,8 +141,6 @@ Level3 MaxSpeed true - true - true true ../../include %(PreprocessorDefinitions);NDEBUG @@ -150,11 +148,9 @@ $(IntDir) false false - AnySuitable - Neither - false - false + Default CompileAsCpp + true true @@ -172,8 +168,6 @@ Level3 MaxSpeed true - true - true true ../../include %(PreprocessorDefinitions);NDEBUG @@ -181,11 +175,9 @@ $(IntDir) false false - AnySuitable - Neither - false - false + Default CompileAsCpp + true true From d52e4039b67164cf2a240bfe79b026b85d9c5db1 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 20 Aug 2019 07:06:11 -0700 Subject: [PATCH 3/4] remove the reset_discards option --- include/mimalloc.h | 1 - src/options.c | 3 +-- src/os.c | 19 ++++--------------- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/include/mimalloc.h b/include/mimalloc.h index d14238a9..9106fdea 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -231,7 +231,6 @@ typedef enum mi_option_e { mi_option_page_reset, mi_option_cache_reset, mi_option_reset_decommits, - mi_option_reset_discards, _mi_option_last } mi_option_t; diff --git a/src/options.c b/src/options.c index f6059ae5..de1ef079 100644 --- a/src/options.c +++ b/src/options.c @@ -64,8 +64,7 @@ static mi_option_desc_t options[_mi_option_last] = { 0, UNINIT, MI_OPTION(large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's { 0, UNINIT, MI_OPTION(page_reset) }, { 0, UNINIT, MI_OPTION(cache_reset) }, - { 0, UNINIT, MI_OPTION(reset_decommits) }, // note: cannot enable this if secure is on - { 0, UNINIT, MI_OPTION(reset_discards) } // note: cannot enable this if secure is on + { 0, UNINIT, MI_OPTION(reset_decommits) } // note: cannot enable this if secure is on }; static void mi_option_init(mi_option_desc_t* desc); diff --git a/src/os.c b/src/os.c index 506e1e6d..7afe447e 100644 --- a/src/os.c +++ b/src/os.c @@ -84,11 +84,9 @@ static size_t mi_os_good_alloc_size(size_t size, size_t alignment) { #if defined(_WIN32) // We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. // So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility) -// Same for DiscardVirtualMemory. (hide MEM_EXTENDED_PARAMETER to compile with older SDK's) +// (hide MEM_EXTENDED_PARAMETER to compile with older SDK's) typedef PVOID(__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ void*, ULONG); -typedef DWORD(__stdcall *PDiscardVirtualMemory)(PVOID,SIZE_T); static PVirtualAlloc2 pVirtualAlloc2 = NULL; -static PDiscardVirtualMemory pDiscardVirtualMemory = NULL; void _mi_os_init(void) { // get the page size @@ -103,7 +101,6 @@ void _mi_os_init(void) { // use VirtualAlloc2FromApp if possible as it is available to Windows store apps pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2FromApp"); if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2"); - pDiscardVirtualMemory = (PDiscardVirtualMemory)GetProcAddress(hDll, "DiscardVirtualMemory"); FreeLibrary(hDll); } // Try to see if large OS pages are supported @@ -558,17 +555,9 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats) #if defined(_WIN32) // Testing shows that for us (on `malloc-large`) MEM_RESET is 2x faster than DiscardVirtualMemory - // (but this is for an access pattern that immediately reuses the memory) - if (mi_option_is_enabled(mi_option_reset_discards) && pDiscardVirtualMemory != NULL) { - DWORD ok = (*pDiscardVirtualMemory)(start, csize); - mi_assert_internal(ok == ERROR_SUCCESS); - if (ok != ERROR_SUCCESS) return false; - } - else { - void* p = VirtualAlloc(start, csize, MEM_RESET, PAGE_READWRITE); - mi_assert_internal(p == start); - if (p != start) return false; - } + void* p = VirtualAlloc(start, csize, MEM_RESET, PAGE_READWRITE); + mi_assert_internal(p == start); + if (p != start) return false; #else #if defined(MADV_FREE) static int advice = MADV_FREE; From 1e0cd575a5a369b3ace3230eca0a001b11aa8d85 Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 20 Aug 2019 07:06:53 -0700 Subject: [PATCH 4/4] do not export DllEntry on windows --- src/alloc-override-win.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alloc-override-win.c b/src/alloc-override-win.c index d1d51b9a..0bd05deb 100644 --- a/src/alloc-override-win.c +++ b/src/alloc-override-win.c @@ -666,7 +666,7 @@ static void mi_patches_at_quick_exit(void) { mi_patches_enable_term(); // enter termination phase and patch realloc/free with a no-op } -__declspec(dllexport) BOOL WINAPI DllEntry(HINSTANCE inst, DWORD reason, LPVOID reserved) { +BOOL WINAPI DllEntry(HINSTANCE inst, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) { __security_init_cookie(); }