From 306a5423364880b190736447267c7bb47e457d46 Mon Sep 17 00:00:00 2001 From: daan Date: Thu, 18 Jul 2019 19:52:29 -0700 Subject: [PATCH] add mimalloc-override header file and use C++ compilation with msvc --- CMakeLists.txt | 1 + ide/vs2017/mimalloc-test.vcxproj | 7 +- ide/vs2017/mimalloc-test.vcxproj.filters | 2 +- ide/vs2017/mimalloc.vcxproj | 6 +- include/mimalloc-override.h | 88 ++++++++++++++++++++++++ src/alloc-override.c | 9 ++- src/memory.c | 2 +- test/main-override.cpp | 6 +- 8 files changed, 101 insertions(+), 20 deletions(-) create mode 100644 include/mimalloc-override.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9de8618..d86d096b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,7 @@ target_link_libraries(mimalloc-static PUBLIC ${mi_libraries}) install(TARGETS mimalloc EXPORT mimalloc DESTINATION ${mi_install_dir} LIBRARY NAMELINK_SKIP) install(TARGETS mimalloc-static EXPORT mimalloc DESTINATION ${mi_install_dir}) install(FILES include/mimalloc.h DESTINATION ${mi_install_dir}/include) +install(FILES include/mimalloc-override.h DESTINATION ${mi_install_dir}/include) install(FILES cmake/mimalloc-config.cmake DESTINATION ${mi_install_dir}/cmake) install(FILES cmake/mimalloc-config-version.cmake DESTINATION ${mi_install_dir}/cmake) install(EXPORT mimalloc DESTINATION ${mi_install_dir}/cmake) diff --git a/ide/vs2017/mimalloc-test.vcxproj b/ide/vs2017/mimalloc-test.vcxproj index 7976af56..8e61a97f 100644 --- a/ide/vs2017/mimalloc-test.vcxproj +++ b/ide/vs2017/mimalloc-test.vcxproj @@ -145,12 +145,7 @@ - - AssemblyAndSourceCode - AssemblyAndSourceCode - AssemblyAndSourceCode - AssemblyAndSourceCode - + diff --git a/ide/vs2017/mimalloc-test.vcxproj.filters b/ide/vs2017/mimalloc-test.vcxproj.filters index 9254f6c0..eb5e70b7 100644 --- a/ide/vs2017/mimalloc-test.vcxproj.filters +++ b/ide/vs2017/mimalloc-test.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files diff --git a/ide/vs2017/mimalloc.vcxproj b/ide/vs2017/mimalloc.vcxproj index bb1818b0..d3b84c45 100644 --- a/ide/vs2017/mimalloc.vcxproj +++ b/ide/vs2017/mimalloc.vcxproj @@ -94,8 +94,9 @@ true ../../include MI_DEBUG=3;%(PreprocessorDefinitions); - Default + CompileAsCpp false + stdcpp17 @@ -112,8 +113,9 @@ true ../../include MI_DEBUG=3;%(PreprocessorDefinitions); - Default + CompileAsCpp false + stdcpp17 diff --git a/include/mimalloc-override.h b/include/mimalloc-override.h new file mode 100644 index 00000000..62036b55 --- /dev/null +++ b/include/mimalloc-override.h @@ -0,0 +1,88 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018,2019 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. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_OVERRIDE_H +#define MIMALLOC_OVERRIDE_H + +#include "mimalloc.h" + +// Standard C allocation +#define malloc(n) mi_malloc(n) +#define calloc(n,c) mi_calloc(n,c) +#define realloc(p,n) mi_realloc(p,n) +#define free(p) mi_free(p) + +#define strdup(s) mi_strdup(s) +#define strndup(s) mi_strndup(s) +#define realpath(f,n) mi_realpath(f,n) + +// Microsoft extensions +#define _expand(p,n) mi_expand(p,n) +#define _msize(p) mi_usable_size(p) +#define _recalloc(p,n,c) mi_recalloc(p,n,c) +#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v) +#define _wdupenv_s(b,n,v) mi_wdupenv_s(b,n,v) + +// Various Posix and Unix variants +#define reallocf(p,n) mi_reallocf(p,n) +#define malloc_size(p) mi_usable_size(p) +#define malloc_usable_size(p) mi_usable_size(p) +#define cfree(p) mi_free(p) + +#define valloc(n) mi_valloc(n) +#define pvalloc(n) mi_pvalloc(n) +#define reallocarray(p,s,n) mi_reallocarray(p,s,n) +#define memalign(a,n) mi_memalign(a,n) +#define aligned_alloc(a,n) mi_aligned_alloc(a,n) +#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n) +#define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n) + +// Microsoft aligned variants +#define _aligned_malloc(n,a) mi_malloc_aligned(n,a) +#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a) +#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a) +#define _aligned_msize(p,a,o) mi_usable_size(p) +#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o) +#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o) +#define _aligned_offset_recalloc(p,s,n,a,o) mi_recalloc_aligned_at(p,s,n,a,o) + + +// ------------------------------------------------------ +// With a C++ compiler we override the new/delete operators. +// see +// ------------------------------------------------------ +#ifdef __cplusplus + #include + + void operator delete(void* p) noexcept { mi_free(p); }; + void operator delete[](void* p) noexcept { mi_free(p); }; + + void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } + void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } + + void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) { mi_free_size(p,n); }; + void operator delete[](void* p, std::size_t n) { mi_free_size(p,n); }; + #endif + + #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) + 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 +#endif + +#endif MIMALLOC_OVERRIDE_H diff --git a/src/alloc-override.c b/src/alloc-override.c index 5ca88af7..a1d671bb 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -19,10 +19,6 @@ terms of the MIT license. A copy of the license can be found in the file // Override system malloc // ------------------------------------------------------ -#if defined(_MSC_VER) -#pragma warning(disable:4273) // inconsistent dll linking -#endif - #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) @@ -62,6 +58,9 @@ terms of the MIT license. A copy of the license can be found in the file MI_INTERPOSE_MI(strdup), MI_INTERPOSE_MI(strndup) }; +#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_attr_noexcept MI_FORWARD1(mi_malloc, size); @@ -94,7 +93,7 @@ terms of the MIT license. A copy of the license can be found in the file 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) + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) void operator delete (void* p, std::size_t n) MI_FORWARD02(mi_free_size,p,n); void operator delete[](void* p, std::size_t n) MI_FORWARD02(mi_free_size,p,n); #endif diff --git a/src/memory.c b/src/memory.c index 83e90b0d..bfbb5e39 100644 --- a/src/memory.c +++ b/src/memory.c @@ -105,7 +105,7 @@ static size_t mi_good_commit_size(size_t size) { } // Return if a pointer points into a region reserved by us. -bool mi_is_in_heap_region(const void* p) { +bool mi_is_in_heap_region(const void* p) mi_attr_noexcept { size_t count = mi_atomic_read(®ions_count); for (size_t i = 0; i < count; i++) { uint8_t* start = (uint8_t*)mi_atomic_read_ptr(®ions[i].start); diff --git a/test/main-override.cpp b/test/main-override.cpp index 3f2bc960..7b562d41 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -40,11 +41,6 @@ int main() { delete t; t = new (std::nothrow) Test(42); delete t; - int err = mi_posix_memalign(&p1,32,60); - if (!err) free(p1); - free(p); - mi_collect(true); - mi_stats_print(NULL); // MIMALLOC_VERBOSE env is set to 2 return 0; }