mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-08-25 16:54:47 +03:00
wip: track allocation locations in debug mode
This commit is contained in:
parent
4090561975
commit
21a95c7449
10 changed files with 257 additions and 141 deletions
|
@ -93,52 +93,55 @@ static inline void* mi_heapx_calloc_aligned(mi_heap_t* heap, size_t count, size_
|
|||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_malloc_aligned_at(heap, size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_malloc_aligned_at(heap, size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
return _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc_aligned_at(heap, size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc_aligned_at(heap, size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc_aligned(heap, size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_calloc_aligned_at(heap, count, size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_calloc_aligned_at(heap, count, size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_calloc_aligned(heap, count, size, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_calloc_aligned(heap, count, size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
mi_decl_allocator void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_malloc_aligned_at(mi_get_default_heap(), size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_malloc_aligned_at(mi_get_default_heap(), size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_source_malloc_aligned(size_t size, size_t alignment MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc_aligned(mi_get_default_heap(), size, alignment MI_SOURCE_ARG);
|
||||
}
|
||||
mi_decl_allocator void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc_aligned(mi_get_default_heap(), size, alignment MI_SOURCE_RET);
|
||||
return mi_source_malloc_aligned(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc_aligned_at(mi_get_default_heap(), size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc_aligned_at(mi_get_default_heap(), size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc_aligned(mi_get_default_heap(), size, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc_aligned(mi_get_default_heap(), size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_calloc_aligned_at(mi_get_default_heap(), count, size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_calloc_aligned_at(mi_get_default_heap(), count, size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_calloc_aligned(mi_get_default_heap(), count, size, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_calloc_aligned(mi_get_default_heap(), count, size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,54 +212,54 @@ static inline void* mi_heapx_recalloc_aligned(mi_heap_t* heap, void* p, size_t n
|
|||
}
|
||||
|
||||
mi_decl_allocator void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_realloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_realloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_realloc_aligned(mi_get_default_heap(), p, newsize, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_realloc_aligned(mi_get_default_heap(), p, newsize, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_rezalloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_rezalloc_aligned(mi_get_default_heap(), p, newsize, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned(mi_get_default_heap(), p, newsize, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_recalloc_aligned_at(mi_get_default_heap(), p, newcount, size, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_recalloc_aligned_at(mi_get_default_heap(), p, newcount, size, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
mi_decl_allocator void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_realloc_aligned_at(heap, p, newsize, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_realloc_aligned_at(heap, p, newsize, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_realloc_aligned(heap, p, newsize, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_realloc_aligned(heap, p, newsize, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heapx_rezalloc_aligned_at(heap, p, newsize, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned_at(heap, p, newsize, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heapx_rezalloc_aligned(heap, p, newsize, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned(heap, p, newsize, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_count_size_overflow(newcount, size, &total)) return NULL;
|
||||
return mi_heapx_rezalloc_aligned_at(heap, p, total, alignment, offset MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned_at(heap, p, total, alignment, offset MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_count_size_overflow(newcount, size, &total)) return NULL;
|
||||
return mi_heapx_rezalloc_aligned(heap, p, total, alignment MI_SOURCE_RET);
|
||||
return mi_heapx_rezalloc_aligned(heap, p, total, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
|
|
@ -48,13 +48,12 @@ int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept
|
|||
if (p == NULL) return EINVAL;
|
||||
if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment
|
||||
if (!_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2
|
||||
mi_heap_t* heap = mi_get_default_heap();
|
||||
void* q;
|
||||
if (alignment <= MI_MAX_ALIGN_SIZE) {
|
||||
q = _mi_heapx_malloc(heap, size MI_SOURCE_RET);
|
||||
q = mi_source_malloc(size MI_SOURCE_RET());
|
||||
}
|
||||
else {
|
||||
q = _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
q = mi_source_malloc_aligned(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
if (q==NULL && size != 0) return ENOMEM;
|
||||
mi_assert_internal(((uintptr_t)q % alignment) == 0);
|
||||
|
@ -63,47 +62,44 @@ int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept
|
|||
}
|
||||
|
||||
void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {
|
||||
mi_heap_t* heap = mi_get_default_heap();
|
||||
void* p;
|
||||
if (alignment <= MI_MAX_ALIGN_SIZE) {
|
||||
p = _mi_heapx_malloc(heap, size MI_SOURCE_RET);
|
||||
p = mi_source_malloc(size MI_SOURCE_RET());
|
||||
}
|
||||
else {
|
||||
p = _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
p = mi_source_malloc_aligned(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
mi_assert_internal(((uintptr_t)p % alignment) == 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_valloc(size_t size) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc_aligned(mi_get_default_heap(), size, _mi_os_page_size() MI_SOURCE_RET);
|
||||
return mi_source_malloc_aligned(size, _mi_os_page_size() MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
void* mi_pvalloc(size_t size) mi_attr_noexcept {
|
||||
size_t psize = _mi_os_page_size();
|
||||
if (size >= SIZE_MAX - psize) return NULL; // overflow
|
||||
size_t asize = ((size + psize - 1) / psize) * psize;
|
||||
return _mi_heapx_malloc_aligned(mi_get_default_heap(), asize, psize MI_SOURCE_RET);
|
||||
return mi_source_malloc_aligned(asize, psize MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {
|
||||
if (alignment==0 || !_mi_is_power_of_two(alignment)) return NULL;
|
||||
if ((size&(alignment-1)) != 0) return NULL; // C11 requires integral multiple, see <https://en.cppreference.com/w/c/memory/aligned_alloc>
|
||||
mi_heap_t* heap = mi_get_default_heap();
|
||||
void* p;
|
||||
if (alignment <= MI_MAX_ALIGN_SIZE) {
|
||||
p = _mi_heapx_malloc(heap, size MI_SOURCE_RET);
|
||||
p = mi_source_malloc(size MI_SOURCE_RET());
|
||||
}
|
||||
else {
|
||||
p = _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
p = mi_source_malloc_aligned(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
mi_assert_internal(((uintptr_t)p % alignment) == 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD
|
||||
mi_heap_t* heap = mi_get_default_heap();
|
||||
void* newp = _mi_heapx_reallocn(heap, p, count, size MI_SOURCE_RET);
|
||||
void* newp = mi_source_reallocn(p, count, size MI_SOURCE_RET());
|
||||
if (newp==NULL) errno = ENOMEM;
|
||||
return newp;
|
||||
}
|
||||
|
@ -119,7 +115,7 @@ unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept {
|
|||
size_t len;
|
||||
for(len = 0; s[len] != 0; len++) { }
|
||||
size_t size = (len+1)*sizeof(unsigned short);
|
||||
unsigned short* p = (unsigned short*)_mi_heapx_malloc(mi_get_default_heap(), size MI_SOURCE_RET);
|
||||
unsigned short* p = (unsigned short*)mi_source_malloc(size MI_SOURCE_RET());
|
||||
if (p != NULL) {
|
||||
memcpy(p,s,size);
|
||||
}
|
||||
|
@ -127,7 +123,7 @@ unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept {
|
|||
}
|
||||
|
||||
unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept {
|
||||
return (unsigned char*)_mi_heapx_strdup(mi_get_default_heap(), (const char*)s MI_SOURCE_RET);
|
||||
return (unsigned char*)mi_source_strdup((const char*)s MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {
|
||||
|
@ -139,7 +135,7 @@ int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {
|
|||
*buf = NULL;
|
||||
}
|
||||
else {
|
||||
*buf = _mi_heapx_strdup(mi_get_default_heap(), p MI_SOURCE_RET);
|
||||
*buf = mi_source_strdup(p MI_SOURCE_RET());
|
||||
if (*buf==NULL) return ENOMEM;
|
||||
if (size != NULL) *size = strlen(p);
|
||||
}
|
||||
|
|
131
src/alloc.c
131
src/alloc.c
|
@ -50,7 +50,7 @@ extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t siz
|
|||
mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta));
|
||||
padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys));
|
||||
padding->delta = (uint32_t)(delta);
|
||||
padding->source = source;
|
||||
padding->source = __mi_source;
|
||||
uint8_t* fill = (uint8_t*)padding - delta;
|
||||
const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes
|
||||
for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; }
|
||||
|
@ -76,11 +76,11 @@ static inline mi_decl_allocator void* mi_heapx_malloc_small(mi_heap_t* heap, siz
|
|||
}
|
||||
|
||||
extern inline mi_decl_allocator void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_malloc_small(heap, size MI_SOURCE_RET);
|
||||
return mi_heapx_malloc_small(heap, size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
extern inline mi_decl_allocator void* mi_malloc_small(size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_malloc_small(mi_get_default_heap(), size MI_SOURCE_RET);
|
||||
return mi_heapx_malloc_small(mi_get_default_heap(), size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
// The main allocation function
|
||||
|
@ -104,10 +104,13 @@ inline mi_decl_allocator void* _mi_heapx_malloc(mi_heap_t* heap, size_t size MI_
|
|||
}
|
||||
|
||||
extern inline mi_decl_allocator void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc(heap, size MI_SOURCE_RET);
|
||||
return _mi_heapx_malloc(heap, size MI_SOURCE_RET());
|
||||
}
|
||||
extern inline mi_decl_allocator void* mi_source_malloc(size_t size MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc(mi_get_default_heap(), size MI_SOURCE_ARG);
|
||||
}
|
||||
extern inline mi_decl_allocator void* mi_malloc(size_t size) mi_attr_noexcept {
|
||||
return _mi_heapx_malloc(mi_get_default_heap(), size MI_SOURCE_RET);
|
||||
return mi_source_malloc(size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +134,7 @@ void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size) {
|
|||
|
||||
// zero initialized small block
|
||||
mi_decl_allocator void* mi_zalloc_small(size_t size) mi_attr_noexcept {
|
||||
void* p = mi_heapx_malloc_small(mi_get_default_heap(), size MI_SOURCE_RET);
|
||||
void* p = mi_heapx_malloc_small(mi_get_default_heap(), size MI_SOURCE_RET());
|
||||
if (p != NULL) {
|
||||
_mi_block_zero_init(_mi_ptr_page(p), p, size); // todo: can we avoid getting the page again?
|
||||
}
|
||||
|
@ -151,11 +154,11 @@ static inline mi_decl_allocator void* mi_heapx_zalloc(mi_heap_t* heap, size_t si
|
|||
}
|
||||
|
||||
extern inline mi_decl_allocator void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc(heap, size MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc(heap, size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_zalloc(size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_zalloc(mi_get_default_heap(), size MI_SOURCE_RET);
|
||||
return mi_heapx_zalloc(mi_get_default_heap(), size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,11 +545,13 @@ static inline mi_decl_allocator void* mi_heapx_calloc(mi_heap_t* heap, size_t co
|
|||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_calloc(heap, count, size MI_SOURCE_RET);
|
||||
return mi_heapx_calloc(heap, count, size MI_SOURCE_RET());
|
||||
}
|
||||
mi_decl_allocator void* mi_source_calloc(size_t count, size_t size MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return mi_heapx_calloc(mi_get_default_heap(), count, size MI_SOURCE_ARG);
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_calloc(size_t count, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_calloc(mi_get_default_heap(), count, size MI_SOURCE_RET);
|
||||
return mi_source_calloc(count, size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
// Uninitialized `calloc`
|
||||
|
@ -557,11 +562,11 @@ static inline mi_decl_allocator void* mi_heapx_mallocn(mi_heap_t* heap, size_t c
|
|||
}
|
||||
|
||||
extern mi_decl_allocator void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_mallocn(heap, count, size MI_SOURCE_RET);
|
||||
return mi_heapx_mallocn(heap, count, size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept {
|
||||
return mi_heapx_mallocn(mi_get_default_heap(), count, size MI_SOURCE_RET);
|
||||
return mi_heapx_mallocn(mi_get_default_heap(), count, size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
// Expand in place or fail
|
||||
|
@ -597,7 +602,7 @@ static mi_decl_allocator void* mi_heapx_realloc(mi_heap_t* heap, void* p, size_t
|
|||
|
||||
|
||||
mi_decl_allocator void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
|
||||
return mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET);
|
||||
return mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* _mi_heapx_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
|
@ -607,49 +612,55 @@ mi_decl_allocator void* _mi_heapx_reallocn(mi_heap_t* heap, void* p, size_t coun
|
|||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
return _mi_heapx_reallocn(heap, p, count, size MI_SOURCE_RET);
|
||||
return _mi_heapx_reallocn(heap, p, count, size MI_SOURCE_RET());
|
||||
}
|
||||
// Reallocate but free `p` on errors
|
||||
mi_decl_allocator void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
|
||||
void* newp = mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET);
|
||||
void* newp = mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET());
|
||||
if (newp==NULL && p!=NULL) mi_free(p);
|
||||
return newp;
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
|
||||
return _mi_heapx_realloc_zero(heap, p, newsize, true MI_SOURCE_RET);
|
||||
return _mi_heapx_realloc_zero(heap, p, newsize, true MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_count_size_overflow(count, size, &total)) return NULL;
|
||||
return _mi_heapx_realloc_zero(heap, p, total, true MI_SOURCE_RET);
|
||||
return _mi_heapx_realloc_zero(heap, p, total, true MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
mi_decl_allocator void* mi_source_realloc(void* p, size_t newsize MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return mi_heapx_realloc(mi_get_default_heap(), p, newsize MI_SOURCE_ARG);
|
||||
}
|
||||
mi_decl_allocator void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return mi_heapx_realloc(mi_get_default_heap(),p,newsize MI_SOURCE_RET);
|
||||
return mi_source_realloc(p, newsize MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_source_reallocn(void* p, size_t count, size_t size MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return _mi_heapx_reallocn(mi_get_default_heap(), p, count, size MI_SOURCE_ARG);
|
||||
}
|
||||
mi_decl_allocator void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
return _mi_heapx_reallocn(mi_get_default_heap(),p,count,size MI_SOURCE_RET);
|
||||
return mi_source_reallocn(p,count,size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
// Reallocate but free `p` on errors
|
||||
mi_decl_allocator void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept {
|
||||
void* newp = mi_heapx_realloc(mi_get_default_heap(), p, newsize MI_SOURCE_RET);
|
||||
void* newp = mi_heapx_realloc(mi_get_default_heap(), p, newsize MI_SOURCE_RET());
|
||||
if (newp==NULL && p!=NULL) mi_free(p);
|
||||
return newp;
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return _mi_heapx_realloc_zero(mi_get_default_heap(), p, newsize, true MI_SOURCE_RET);
|
||||
return _mi_heapx_realloc_zero(mi_get_default_heap(), p, newsize, true MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
mi_decl_allocator void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_count_size_overflow(count, size, &total)) return NULL;
|
||||
return _mi_heapx_realloc_zero(mi_get_default_heap(), p, total, true MI_SOURCE_RET);
|
||||
return _mi_heapx_realloc_zero(mi_get_default_heap(), p, total, true MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
|
@ -659,7 +670,7 @@ mi_decl_allocator void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_
|
|||
// ------------------------------------------------------
|
||||
|
||||
// `strdup` using mi_malloc
|
||||
mi_decl_allocator char* _mi_heapx_strdup(mi_heap_t* heap, const char* s MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
static char* mi_heapx_strdup(mi_heap_t* heap, const char* s MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
if (s == NULL) return NULL;
|
||||
size_t n = strlen(s);
|
||||
char* t = (char*)_mi_heapx_malloc(heap, n+1 MI_SOURCE_ARG);
|
||||
|
@ -668,10 +679,13 @@ mi_decl_allocator char* _mi_heapx_strdup(mi_heap_t* heap, const char* s MI_SOUR
|
|||
}
|
||||
|
||||
char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept {
|
||||
return _mi_heapx_strdup(heap, s MI_SOURCE_RET);
|
||||
return mi_heapx_strdup(heap, s MI_SOURCE_RET());
|
||||
}
|
||||
char* mi_source_strdup(const char* s MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return mi_heapx_strdup(mi_get_default_heap(), s MI_SOURCE_ARG);
|
||||
}
|
||||
char* mi_strdup(const char* s) mi_attr_noexcept {
|
||||
return _mi_heapx_strdup(mi_get_default_heap(), s MI_SOURCE_RET);
|
||||
return mi_source_strdup(s MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
// `strndup` using mi_malloc
|
||||
|
@ -687,10 +701,13 @@ static char* mi_heapx_strndup(mi_heap_t* heap, const char* s, size_t n MI_SOURC
|
|||
}
|
||||
|
||||
char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept {
|
||||
return mi_heapx_strndup(heap, s, n MI_SOURCE_RET);
|
||||
return mi_heapx_strndup(heap, s, n MI_SOURCE_RET());
|
||||
}
|
||||
char* mi_source_strndup(const char* s, size_t n MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return mi_heapx_strndup(mi_get_default_heap(), s, n MI_SOURCE_ARG);
|
||||
}
|
||||
char* mi_strndup(const char* s, size_t n) mi_attr_noexcept {
|
||||
return mi_heapx_strndup(mi_get_default_heap(), s, n MI_SOURCE_RET);
|
||||
return mi_source_strndup(s, n MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
#ifndef __wasi__
|
||||
|
@ -747,11 +764,13 @@ static char* mi_heapx_realpath(mi_heap_t* heap, const char* fname, char* resolve
|
|||
#endif
|
||||
|
||||
char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {
|
||||
return mi_heapx_realpath(heap, fname, resolved_name MI_SOURCE_RET);
|
||||
return mi_heapx_realpath(heap, fname, resolved_name MI_SOURCE_RET());
|
||||
}
|
||||
char* mi_source_realpath(const char* fname, char* resolved_name MI_SOURCE_PARAM) mi_attr_noexcept {
|
||||
return mi_heapx_realpath(mi_get_default_heap(), fname, resolved_name MI_SOURCE_ARG);
|
||||
}
|
||||
|
||||
char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {
|
||||
return mi_heapx_realpath(mi_get_default_heap(), fname, resolved_name MI_SOURCE_RET);
|
||||
return mi_heapx_realpath(mi_get_default_heap(), fname, resolved_name MI_SOURCE_RET());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -807,52 +826,62 @@ static bool mi_try_new_handler(bool nothrow) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static mi_decl_noinline void* mi_heapx_try_new(mi_heap_t* heap, size_t size, bool nothrow MI_SOURCE_PARAM) {
|
||||
static mi_decl_noinline void* mi_source_try_new(size_t size, bool nothrow MI_SOURCE_PARAM) {
|
||||
void* p = NULL;
|
||||
while(p == NULL && mi_try_new_handler(nothrow)) {
|
||||
p = _mi_heapx_malloc(heap, size MI_SOURCE_ARG);
|
||||
p = mi_source_malloc(size MI_SOURCE_ARG);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void* mi_heapx_new(size_t size MI_SOURCE_PARAM) {
|
||||
mi_heap_t* const heap = mi_get_default_heap();
|
||||
void* p = _mi_heapx_malloc(heap, size MI_SOURCE_ARG);
|
||||
if (mi_unlikely(p == NULL)) return mi_heapx_try_new(heap, size, false MI_SOURCE_ARG);
|
||||
inline void* mi_source_new(size_t size MI_SOURCE_PARAM) {
|
||||
void* p = mi_source_malloc(size MI_SOURCE_ARG);
|
||||
if (mi_unlikely(p == NULL)) return mi_source_try_new(size, false MI_SOURCE_ARG);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_new(size_t size) {
|
||||
return mi_heapx_new(size MI_SOURCE_RET);
|
||||
return mi_source_new(size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
void* mi_new_nothrow(size_t size) {
|
||||
mi_heap_t* const heap = mi_get_default_heap();
|
||||
void* p = _mi_heapx_malloc(heap, size MI_SOURCE_RET);
|
||||
if (mi_unlikely(p == NULL)) return mi_heapx_try_new(heap, size, true MI_SOURCE_RET);
|
||||
void* mi_source_new_nothrow(size_t size MI_SOURCE_PARAM) {
|
||||
void* p = mi_source_malloc(size MI_SOURCE_ARG);
|
||||
if (mi_unlikely(p == NULL)) return mi_source_try_new(size, true MI_SOURCE_ARG);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_new_aligned(size_t size, size_t alignment) {
|
||||
mi_heap_t* const heap = mi_get_default_heap();
|
||||
void* mi_new_nothrow(size_t size) {
|
||||
return mi_source_new_nothrow(size MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
void* mi_source_new_aligned(size_t size, size_t alignment MI_SOURCE_PARAM) {
|
||||
void* p;
|
||||
do {
|
||||
p = _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
p = mi_source_malloc_aligned(size, alignment MI_SOURCE_ARG);
|
||||
}
|
||||
while(p == NULL && mi_try_new_handler(false));
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_new_aligned_nothrow(size_t size, size_t alignment) {
|
||||
mi_heap_t* const heap = mi_get_default_heap();
|
||||
void* mi_new_aligned(size_t size, size_t alignment) {
|
||||
return mi_source_new_aligned(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
void* mi_source_new_aligned_nothrow(size_t size, size_t alignment MI_SOURCE_PARAM) {
|
||||
void* p;
|
||||
do {
|
||||
p = _mi_heapx_malloc_aligned(heap, size, alignment MI_SOURCE_RET);
|
||||
p = mi_source_malloc_aligned(size, alignment MI_SOURCE_ARG);
|
||||
}
|
||||
while(p == NULL && mi_try_new_handler(true));
|
||||
return p;
|
||||
}
|
||||
|
||||
void* mi_new_aligned_nothrow(size_t size, size_t alignment) {
|
||||
return mi_source_new_aligned_nothrow(size, alignment MI_SOURCE_RET());
|
||||
}
|
||||
|
||||
|
||||
void* mi_new_n(size_t count, size_t size) {
|
||||
size_t total;
|
||||
if (mi_unlikely(mi_count_size_overflow(count, size, &total))) {
|
||||
|
@ -860,7 +889,7 @@ void* mi_new_n(size_t count, size_t size) {
|
|||
return NULL;
|
||||
}
|
||||
else {
|
||||
return mi_heapx_new(total MI_SOURCE_RET);
|
||||
return mi_source_new(total MI_SOURCE_RET());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,7 +897,7 @@ void* mi_new_realloc(void* p, size_t newsize) {
|
|||
mi_heap_t* const heap = mi_get_default_heap();
|
||||
void* q;
|
||||
do {
|
||||
q = mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET);
|
||||
q = mi_heapx_realloc(heap, p, newsize MI_SOURCE_RET());
|
||||
} while (q == NULL && mi_try_new_handler(false));
|
||||
return q;
|
||||
}
|
||||
|
@ -882,7 +911,7 @@ void* mi_new_reallocn(void* p, size_t newcount, size_t size) {
|
|||
}
|
||||
void* q;
|
||||
do {
|
||||
q = mi_heapx_realloc(heap, p, total MI_SOURCE_RET);
|
||||
q = mi_heapx_realloc(heap, p, total MI_SOURCE_RET());
|
||||
} while (q == NULL && mi_try_new_handler(false));
|
||||
return q;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef struct mi_option_desc_s {
|
|||
static mi_option_desc_t options[_mi_option_last] =
|
||||
{
|
||||
// stable options
|
||||
{ MI_DEBUG, UNINIT, MI_OPTION(show_errors) },
|
||||
{ 1, UNINIT, MI_OPTION(show_errors) },
|
||||
{ 0, UNINIT, MI_OPTION(show_stats) },
|
||||
{ 0, UNINIT, MI_OPTION(verbose) },
|
||||
|
||||
|
@ -381,33 +381,73 @@ void _mi_error_message(int err, const char* fmt, ...) {
|
|||
mi_call_error_handler(err);
|
||||
}
|
||||
|
||||
#if defined(MI_PADDING) && defined(MI_ENCODE_FREELIST)
|
||||
const char* _mi_debug_fname_base = "mimalloc_fname_base";
|
||||
#endif
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// compressed location:
|
||||
// lsb=1: bit 63-19: relative file name char* (to `mi_fname_base`), bit 18-1: line number
|
||||
// lsb=0: bit 63-01: return address
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
static const char* mi_debug_fname_base = "mimalloc_fname_base";
|
||||
|
||||
#define MI_FNAME_SHIFT 16
|
||||
#define MI_LINE_SHIFT (MI_FNAME_SHIFT + MI_INTPTR_SHIFT)
|
||||
#define MI_LINE_MASK ((1L << MI_LINE_SHIFT) - 1)
|
||||
|
||||
mi_source_t mi_source_ret(void* return_address) {
|
||||
mi_source_t source = { ((intptr_t)return_address << 1) };
|
||||
return source;
|
||||
}
|
||||
|
||||
mi_source_t mi_source_loc(const char* fname, int lineno ) {
|
||||
ptrdiff_t delta = fname - mi_debug_fname_base;
|
||||
mi_assert_internal(((delta << MI_FNAME_SHIFT) >> MI_FNAME_SHIFT) == delta);
|
||||
mi_source_t source = { ((((intptr_t)delta) << MI_FNAME_SHIFT) | ((lineno << 1) & MI_LINE_MASK) | 1) };
|
||||
return source;
|
||||
}
|
||||
|
||||
void* mi_source_unpack(mi_source_t source, const char** fname, int* lineno) {
|
||||
*fname = NULL;
|
||||
*lineno = 0;
|
||||
if (source.src == 0) {
|
||||
return NULL;
|
||||
}
|
||||
else if ((source.src & 1) == 1) {
|
||||
*fname = (const char*)(mi_debug_fname_base + ((source.src >> MI_LINE_SHIFT) << MI_INTPTR_SHIFT) );
|
||||
*lineno = (source.src & MI_LINE_MASK) >> 1;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return ((void*)(source.src >> 1));
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// Error message for a specific heap block
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
void _mi_page_block_error_message(int err, const mi_page_t* page, const mi_block_t* block, const char* msg) {
|
||||
#if defined(MI_PADDING) && defined(MI_ENCODE_FREELIST)
|
||||
const size_t bsize = mi_page_usable_block_size(page);
|
||||
const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + bsize);
|
||||
const size_t size = (padding->delta <= bsize ? bsize - padding->delta : bsize);
|
||||
if (padding->source==0) {
|
||||
mi_show_error_message("%s: at block %p of size %zu\n", msg, block, size);
|
||||
}
|
||||
else if ((padding->source & 1) == 0) {
|
||||
const char* fname;
|
||||
int lineno;
|
||||
void* return_addr = mi_source_unpack(padding->source, &fname, &lineno);
|
||||
if (return_addr != NULL) {
|
||||
#ifdef _MSC_VER
|
||||
const char* hint = " hint: paste the code address in the disassembly window in the debugger to find the source location.\n";
|
||||
#else
|
||||
const char* hint = "";
|
||||
#endif
|
||||
mi_show_error_message("%s: at block %p of size %zu allocated at 0x%p.\n%s", msg, block, size, (void*)(padding->source >> 1), hint);
|
||||
mi_show_error_message("%s: at block %p of size %zu allocated at 0x%p.\n%s", msg, block, size, return_addr, hint);
|
||||
}
|
||||
else if (fname != NULL) {
|
||||
mi_show_error_message("%s: at block %p of size %zu allocated at %s:%i.\n", msg, block, size, fname, lineno);
|
||||
}
|
||||
else {
|
||||
const char* fname = _mi_debug_fname_base + ((int32_t)(padding->source >> 32));
|
||||
size_t lineno = ((uint32_t)padding->source) >> 1;
|
||||
mi_show_error_message("%s: at block %p of size %zu allocated at %s:%zu", msg, block, size, fname, lineno);
|
||||
mi_show_error_message("%s: at block %p of size %zu.\n", msg, block, mi_page_usable_block_size(page));
|
||||
}
|
||||
#else
|
||||
mi_show_error_message("%s: at block %p of size %zu", msg, block, mi_page_usable_block_size(page));
|
||||
mi_show_error_message("%s: at block %p of size %zu.\n", msg, block, mi_page_usable_block_size(page));
|
||||
#endif
|
||||
mi_call_error_handler(err);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue