diff --git a/ide/vs2022/mimalloc.vcxproj b/ide/vs2022/mimalloc.vcxproj index 0a45006c..69434c21 100644 --- a/ide/vs2022/mimalloc.vcxproj +++ b/ide/vs2022/mimalloc.vcxproj @@ -116,7 +116,7 @@ true true ../../include - MI_DEBUG=3;%(PreprocessorDefinitions); + MI_DEBUG_TRACE=1;MI_DEBUG=3;%(PreprocessorDefinitions); CompileAsCpp false stdcpp20 diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index b94bf2a3..53932b2d 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -256,6 +256,12 @@ static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { return ((sz / alignment) * alignment); } } + +// Is aligned? +static inline bool _mi_is_aligned(void* p, size_t alignment) { + mi_assert_internal(alignment != 0); + return (((uintptr_t)p % alignment) == 0); +} // Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`. static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) { diff --git a/src/alloc.c b/src/alloc.c index 4bf5bd53..730f8870 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -124,9 +124,9 @@ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc_small(size_t si } // The main allocation function -extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { - if mi_likely(size + MI_PADDING_SIZE <= MI_SMALL_SIZE_MAX + MI_PADDING_MINSIZE) { - return mi_heap_malloc_small(heap, size); +extern inline void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept { + if mi_likely(size + MI_PADDING_SIZE <= MI_SMALL_SIZE_MAX + MI_PADDING_MINSIZE) { + return mi_heap_malloc_small_zero(heap, size, zero); } else { @@ -236,7 +236,7 @@ static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, si static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { size_t size; size_t wrong; - if (mi_unlikely(!mi_verify_padding(page,block,&size,&wrong))) { + if mi_unlikely(!mi_verify_padding(page,block,&size,&wrong)) { _mi_show_block_trace_with_predecessor(page, block, NULL); _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong ); } @@ -716,7 +716,9 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) memset((uint8_t*)newp + start, 0, newsize - start); } if mi_likely(p != NULL) { - _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + if mi_likely(_mi_is_aligned(p, sizeof(uintptr_t))) { + _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + } mi_free(p); // only free the original pointer if successful } } diff --git a/src/init.c b/src/init.c index 09152562..60cdd3fe 100644 --- a/src/init.c +++ b/src/init.c @@ -554,6 +554,25 @@ static void mi_detect_cpu_features(void) { } #endif +#if defined(_WIN32) && (MI_DEBUG_TRACE > 0) +#include +static void mi_debug_init(void) { + if (SymInitialize(GetCurrentProcess(), NULL, TRUE) != TRUE) { // initialize here as it is single threaded. + _mi_warning_message("unable to initialize debug symbol information (error 0x%x)", GetLastError()); + } +} +static void mi_debug_done(void) { + SymCleanup(GetCurrentProcess()); +} +#else +static void mi_debug_init(void) { + // nothing +} +static void mi_debug_done(void) { + // nothing +} +#endif + // Initialize the process; called by thread_init or the process loader void mi_process_init(void) mi_attr_noexcept { // ensure we are called once @@ -570,6 +589,7 @@ void mi_process_init(void) mi_attr_noexcept { _mi_verbose_message("debug level : %d\n", MI_DEBUG); #endif _mi_verbose_message("secure level: %d\n", MI_SECURE); + mi_debug_init(); mi_thread_init(); #if defined(_WIN32) && !defined(MI_SHARED_LIB) @@ -578,7 +598,7 @@ void mi_process_init(void) mi_attr_noexcept { // will not call _mi_thread_done on the (still executing) main thread. See issue #508. FlsSetValue(mi_fls_key, NULL); #endif - + mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { @@ -624,6 +644,7 @@ static void mi_process_done(void) { mi_stats_print(NULL); } mi_allocator_done(); + mi_debug_done(); _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); os_preloading = true; // don't call the C runtime anymore } diff --git a/src/options.c b/src/options.c index 63d629eb..4cd45724 100644 --- a/src/options.c +++ b/src/options.c @@ -425,21 +425,14 @@ void _mi_stack_trace_print(const char* msg, void** strace, size_t len, const mi_ info->MaxNameLen = 255; info->SizeOfStruct = sizeof(SYMBOL_INFO); HANDLE current_process = GetCurrentProcess(); - bool initialized = (SymInitialize(current_process, NULL, TRUE) == TRUE); for (size_t i = 0; i < len && strace[i] != NULL; i++) { - if (!initialized) { - _mi_fprintf(NULL, NULL, " %2zu: %8p: \n", i, strace[i]); - } - else if (SymFromAddr(current_process, (DWORD64)(strace[i]), 0, info)) { + if (SymFromAddr(current_process, (DWORD64)(strace[i]), 0, info)) { _mi_fprintf(NULL, NULL, " %2zu: %8p: %s\n", i, strace[i], info->Name); } else { _mi_fprintf(NULL, NULL, " %2zu: %8p: \n", i, strace[i], GetLastError()); } - } - if (initialized) { - SymCleanup(current_process); - } + } } } #elif (MI_DEBUG_TRACE > 0) && (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__))