diff options
author | daan <daanl@outlook.com> | 2019-10-17 18:24:35 -0700 |
---|---|---|
committer | daan <daanl@outlook.com> | 2019-10-17 18:24:35 -0700 |
commit | 4b15e2ed9764824006d3bb56e3659d1b11bddb33 (patch) | |
tree | 36e2642c9bbdcfff8b5948631d750365df1c335f /include/mimalloc-internal.h | |
parent | 25dca38ef9cc7b149c00cdf34be1552a0864de17 (diff) | |
parent | fdfa6ed2602f2e6cbd6d5d466b24a7e447cc0e42 (diff) |
merge from dev
Diffstat (limited to 'include/mimalloc-internal.h')
-rw-r--r-- | include/mimalloc-internal.h | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 240f1fb..b1c468b 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -10,7 +10,7 @@ terms of the MIT license. A copy of the license can be found in the file #include "mimalloc-types.h" -#if defined(MI_MALLOC_OVERRIDE) && defined(__APPLE__) +#if defined(MI_MALLOC_OVERRIDE) && (defined(__APPLE__) || defined(__OpenBSD__)) #define MI_TLS_RECURSE_GUARD #endif @@ -20,9 +20,9 @@ terms of the MIT license. A copy of the license can be found in the file #define mi_trace_message(...) #endif - // "options.c" -void _mi_fprintf(FILE* out, const char* fmt, ...); +void _mi_fputs(mi_output_fun* out, const char* prefix, const char* message); +void _mi_fprintf(mi_output_fun* out, const char* fmt, ...); void _mi_error_message(const char* fmt, ...); void _mi_warning_message(const char* fmt, ...); void _mi_verbose_message(const char* fmt, ...); @@ -44,24 +44,24 @@ size_t _mi_os_large_page_size(); void _mi_os_init(void); // called from process init void* _mi_os_alloc(size_t size, mi_stats_t* stats); // to allocate thread local data void _mi_os_free(void* p, size_t size, mi_stats_t* stats); // to free thread local data +size_t _mi_os_good_alloc_size(size_t size); bool _mi_os_protect(void* addr, size_t size); bool _mi_os_unprotect(void* addr, size_t size); -bool _mi_os_commit(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* stats); bool _mi_os_decommit(void* p, size_t size, mi_stats_t* stats); bool _mi_os_reset(void* p, size_t size, mi_stats_t* stats); -bool _mi_os_unreset(void* p, size_t size, mi_stats_t* stats); -void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, mi_os_tld_t* tld); +bool _mi_os_unreset(void* p, size_t size, bool* is_zero, mi_stats_t* stats); +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld); /* // memory.c -void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool commit, size_t* id, mi_os_tld_t* tld); -void* _mi_mem_alloc(size_t size, bool commit, size_t* id, mi_os_tld_t* tld); +void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* id, mi_os_tld_t* tld); void _mi_mem_free(void* p, size_t size, size_t id, mi_stats_t* stats); bool _mi_mem_reset(void* p, size_t size, mi_stats_t* stats); -bool _mi_mem_unreset(void* p, size_t size, mi_stats_t* stats); -bool _mi_mem_commit(void* p, size_t size, mi_stats_t* stats); +bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_stats_t* stats); +bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); bool _mi_mem_protect(void* addr, size_t size); bool _mi_mem_unprotect(void* addr, size_t size); @@ -112,6 +112,7 @@ void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero); void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero); mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); bool _mi_free_delayed_block(mi_block_t* block); +void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size); #if MI_DEBUG>1 bool _mi_page_is_valid(mi_page_t* page); @@ -166,10 +167,13 @@ bool _mi_page_is_valid(mi_page_t* page); #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX) static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { #if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5 -#if (MI_INTPTR_SIZE == 4) +#include <limits.h> // UINT_MAX, ULONG_MAX +#if (SIZE_MAX == UINT_MAX) return __builtin_umul_overflow(count, size, total); -#else +#elif (SIZE_MAX == ULONG_MAX) return __builtin_umull_overflow(count, size, total); +#else + return __builtin_umulll_overflow(count, size, total); #endif #else /* __builtin_umul_overflow is unavailable */ *total = count * size; @@ -178,10 +182,12 @@ static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { #endif } -// Align upwards -static inline uintptr_t _mi_is_power_of_two(uintptr_t x) { +// Is `x` a power of two? (0 is considered a power of two) +static inline bool _mi_is_power_of_two(uintptr_t x) { return ((x & (x - 1)) == 0); } + +// Align upwards static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { uintptr_t mask = alignment - 1; if ((alignment & mask) == 0) { // power of two? @@ -196,6 +202,14 @@ static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { return (sz / alignment) * alignment; } +// Is memory zero initialized? +static inline bool mi_mem_is_zero(void* p, size_t size) { + for (size_t i = 0; i < size; i++) { + if (((uint8_t*)p)[i] != 0) return false; + } + return true; +} + // Align a byte size to a size in _machine words_, // i.e. byte size == `wsize*sizeof(void*)`. @@ -204,6 +218,11 @@ static inline size_t _mi_wsize_from_size(size_t size) { return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); } + +/* ----------------------------------------------------------- + The thread local default heap +----------------------------------------------------------- */ + extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap extern mi_heap_t _mi_heap_main; // statically allocated main backing heap extern bool _mi_process_is_initialized; @@ -235,6 +254,10 @@ static inline bool mi_heap_is_initialized(mi_heap_t* heap) { return (heap != &_mi_heap_empty); } +/* ----------------------------------------------------------- + Pages +----------------------------------------------------------- */ + static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) { mi_assert_internal(size <= MI_SMALL_SIZE_MAX); return heap->pages_free_direct[_mi_wsize_from_size(size)]; @@ -245,7 +268,6 @@ static inline mi_page_t* _mi_get_free_small_page(size_t size) { return _mi_heap_get_free_small_page(mi_get_default_heap(), size); } - // Segment that contains the pointer static inline mi_segment_t* _mi_ptr_segment(const void* p) { // mi_assert_internal(p != NULL); @@ -359,19 +381,19 @@ static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) // Page flags //----------------------------------------------------------- static inline bool mi_page_is_in_full(const mi_page_t* page) { - return page->flags.in_full; + return page->flags.x.in_full; } static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) { - page->flags.in_full = in_full; + page->flags.x.in_full = in_full; } static inline bool mi_page_has_aligned(const mi_page_t* page) { - return page->flags.has_aligned; + return page->flags.x.has_aligned; } static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) { - page->flags.has_aligned = has_aligned; + page->flags.x.has_aligned = has_aligned; } |