mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-27 13:33:18 +08:00
This commit is contained in:
parent
5f607e0f58
commit
8203f3dcfa
@ -122,16 +122,6 @@ void* mi_calloc(size_t count, size_t size);
|
||||
/// are uninitialized.
|
||||
void* mi_realloc(void* p, size_t newsize);
|
||||
|
||||
/// Reallocate memory to \a newsize bytes, with extra memory initialized to zero.
|
||||
/// @param p Pointer to a previously allocated block (or \a NULL).
|
||||
/// @param newsize The new required size in bytes.
|
||||
/// @returns A pointer to a re-allocated block of \a newsize bytes, or \a NULL
|
||||
/// if out of memory.
|
||||
///
|
||||
/// If the \a newsize is larger than the original allocated size of \a p,
|
||||
/// the extra bytes are initialized to zero.
|
||||
void* mi_rezalloc(void* p, size_t newsize);
|
||||
|
||||
/// Re-allocate memory to \a count elements of \a size bytes, with extra memory initialized to zero.
|
||||
/// @param p Pointer to a previously allocated block (or \a NULL).
|
||||
/// @param count The number of elements.
|
||||
@ -141,11 +131,9 @@ void* mi_rezalloc(void* p, size_t newsize);
|
||||
///
|
||||
/// If there is no overflow, it behaves exactly like `mi_rezalloc(p,count*size)`.
|
||||
/// @see mi_reallocn()
|
||||
/// @see mi_rezalloc()
|
||||
/// @see [recallocarray()](http://man.openbsd.org/reallocarray) (on BSD).
|
||||
void* mi_recalloc(void* p, size_t count, size_t size);
|
||||
|
||||
|
||||
/// Try to re-allocate memory to \a newsize bytes _in place_.
|
||||
/// @param p pointer to previously allocated memory (or \a NULL).
|
||||
/// @param newsize the new required size in bytes.
|
||||
@ -180,7 +168,6 @@ void* mi_mallocn(size_t count, size_t size);
|
||||
/// if out of memory or if \a count * \a size overflows.
|
||||
///
|
||||
/// If there is no overflow, it behaves exactly like `mi_realloc(p,count*size)`.
|
||||
/// @see mi_recalloc()
|
||||
/// @see [reallocarray()](<http://man.openbsd.org/reallocarray>) (on BSD)
|
||||
void* mi_reallocn(void* p, size_t count, size_t size);
|
||||
|
||||
@ -383,8 +370,6 @@ void* mi_malloc_aligned(size_t size, size_t alignment);
|
||||
void* mi_zalloc_aligned(size_t size, size_t alignment);
|
||||
void* mi_calloc_aligned(size_t count, size_t size, size_t alignment);
|
||||
void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment);
|
||||
void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment);
|
||||
void* mi_recalloc_aligned(void* p, size_t count, size_t size, size_t alignment);
|
||||
|
||||
/// Allocate \a size bytes aligned by \a alignment at a specified \a offset.
|
||||
/// @param size number of bytes to allocate.
|
||||
@ -400,8 +385,6 @@ void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset);
|
||||
void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset);
|
||||
void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset);
|
||||
void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
|
||||
void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset);
|
||||
void* mi_recalloc_aligned_at(void* p, size_t count, size_t size, size_t alignment, size_t offset);
|
||||
|
||||
/// \}
|
||||
|
||||
@ -488,6 +471,18 @@ char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n);
|
||||
/// @see mi_realpath()
|
||||
char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name);
|
||||
|
||||
void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize);
|
||||
void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size);
|
||||
void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize);
|
||||
|
||||
void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
|
||||
void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
|
||||
void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment);
|
||||
void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset);
|
||||
void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment);
|
||||
void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset);
|
||||
void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment);
|
||||
void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset);
|
||||
|
||||
/// \}
|
||||
|
||||
@ -522,20 +517,20 @@ char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name);
|
||||
/// Re-allocate to \a count blocks of type \a tp.
|
||||
#define mi_reallocn_tp(p,tp,count) ((tp*)mi_reallocn(p,count,sizeof(tp)))
|
||||
|
||||
/// Re-allocate to \a count zero-initialized blocks of type \a tp.
|
||||
#define mi_recalloc_tp(p,tp,count) ((tp*)mi_recalloc(p,count,sizeof(tp)))
|
||||
|
||||
/// Allocate a block of type \a tp in a heap \a hp.
|
||||
#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_malloc(hp,sizeof(tp)))
|
||||
#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
|
||||
|
||||
/// Allocate a zero-initialized block of type \a tp in a heap \a hp.
|
||||
#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_zalloc(hp,sizeof(tp)))
|
||||
#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
|
||||
|
||||
/// Allocate \a count zero-initialized blocks of type \a tp in a heap \a hp.
|
||||
#define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_calloc(hp,count,sizeof(tp)))
|
||||
#define mi_heap_calloc_tp(hp,tp,count) ((tp*)mi_heap_calloc(hp,count,sizeof(tp)))
|
||||
|
||||
/// Allocate \a count blocks of type \a tp in a heap \a hp.
|
||||
#define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_mallocn(hp,count,sizeof(tp)))
|
||||
#define mi_heap_mallocn_tp(hp,tp,count) ((tp*)mi_heap_mallocn(hp,count,sizeof(tp)))
|
||||
|
||||
/// Re-allocate to \a count blocks of type \a tp in a heap \a hp.
|
||||
#define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp)))
|
||||
|
||||
/// \}
|
||||
|
||||
@ -632,6 +627,40 @@ void mi_option_set(mi_option_t option, long value);
|
||||
void mi_option_set_default(mi_option_t option, long value);
|
||||
|
||||
|
||||
/// \}
|
||||
|
||||
/// \defgroup posix Posix
|
||||
///
|
||||
/// `mi_` prefixed implementations of various Posix, Unix, and C++ allocation functions.
|
||||
/// Defined for convenience as all redirect to the regular mimalloc API.
|
||||
///
|
||||
/// \{
|
||||
|
||||
void* mi_recalloc(void* p, size_t count, size_t size);
|
||||
size_t mi_malloc_size(const void* p);
|
||||
size_t mi_malloc_usable_size(const void *p);
|
||||
void mi_cfree(void* p);
|
||||
|
||||
int mi_posix_memalign(void** p, size_t alignment, size_t size);
|
||||
int mi__posix_memalign(void** p, size_t alignment, size_t size);
|
||||
void* mi_memalign(size_t alignment, size_t size);
|
||||
void* mi_valloc(size_t size);
|
||||
|
||||
void* mi_pvalloc(size_t size);
|
||||
void* mi_aligned_alloc(size_t alignment, size_t size);
|
||||
void* mi_reallocarray(void* p, size_t count, size_t size);
|
||||
|
||||
void mi_free_size(void* p, size_t size);
|
||||
void mi_free_size_aligned(void* p, size_t size, size_t alignment);
|
||||
void mi_free_aligned(void* p, size_t alignment);
|
||||
|
||||
/// Only defined in C++ compilation; raise `std::bad_alloc` exception on failure.
|
||||
void* mi_new(std::size_t n) noexcept(false);
|
||||
|
||||
/// Only defined in C++ compilation; raise `std::bad_alloc` exception on failure.
|
||||
void* mi_new_aligned(std::size_t n, std::align_val_t alignment) noexcept(false);
|
||||
|
||||
|
||||
/// \}
|
||||
|
||||
/*! \page build Building
|
||||
|
@ -88,7 +88,7 @@ void _mi_stats_done(mi_stats_t* stats);
|
||||
// "alloc.c"
|
||||
void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept; // called from `_mi_malloc_generic`
|
||||
void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero);
|
||||
void* _mi_realloc_zero(void* p, 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);
|
||||
void _mi_free_delayed_block(mi_block_t* block);
|
||||
|
||||
|
@ -104,8 +104,6 @@ mi_decl_export mi_decl_allocator void* mi_zalloc(size_t size) mi_attr_no
|
||||
mi_decl_export mi_decl_allocator void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_allocator void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_allocator void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3);
|
||||
|
||||
mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept;
|
||||
@ -113,6 +111,7 @@ mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept;
|
||||
mi_decl_export void mi_collect(bool force) mi_attr_noexcept;
|
||||
mi_decl_export void mi_stats_print(FILE* out) mi_attr_noexcept;
|
||||
mi_decl_export void mi_stats_reset(void) mi_attr_noexcept;
|
||||
mi_decl_export int mi_version(void) mi_attr_noexcept;
|
||||
|
||||
mi_decl_export void mi_process_init(void) mi_attr_noexcept;
|
||||
mi_decl_export void mi_thread_init(void) mi_attr_noexcept;
|
||||
@ -129,22 +128,13 @@ mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_fre
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
|
||||
mi_decl_export mi_decl_allocator void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
|
||||
mi_decl_export mi_decl_allocator void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);
|
||||
mi_decl_export mi_decl_allocator void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_recalloc_aligned(void* p, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3);
|
||||
mi_decl_export mi_decl_allocator void* mi_recalloc_aligned_at(void* p, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Heaps
|
||||
@ -166,10 +156,23 @@ mi_decl_export mi_decl_allocator void* mi_heap_calloc(mi_heap_t* heap, size_t co
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3);
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3);
|
||||
|
||||
mi_decl_export char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept;
|
||||
mi_decl_export char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept;
|
||||
mi_decl_export char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept;
|
||||
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export 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 mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export 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 mi_attr_malloc mi_attr_alloc_size(2);
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);
|
||||
mi_decl_export 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 mi_attr_malloc mi_attr_alloc_size2(2, 3);
|
||||
mi_decl_export mi_decl_allocator void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(3);
|
||||
mi_decl_export 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 mi_attr_malloc mi_attr_alloc_size(3);
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Analysis
|
||||
@ -201,14 +204,13 @@ mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_b
|
||||
#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))
|
||||
#define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp)))
|
||||
#define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp)))
|
||||
|
||||
#define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp)))
|
||||
#define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp)))
|
||||
|
||||
#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
|
||||
#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
|
||||
#define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp)))
|
||||
#define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp)))
|
||||
#define mi_heap_reallocn_tp(hp,tp,n) ((tp*)mi_heap_reallocn(hp,n,sizeof(tp)))
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@ -240,6 +242,7 @@ mi_decl_export void mi_option_set_default(mi_option_t option, long value);
|
||||
// mi prefixed implementations of various posix, unix, and C++ allocation functions.
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
mi_decl_export void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept;
|
||||
mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
|
||||
mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
|
||||
|
@ -52,50 +52,69 @@ static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* heap, size_t size, size_t
|
||||
return aligned_p;
|
||||
}
|
||||
|
||||
static void* mi_malloc_zero_aligned_at(size_t size, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {
|
||||
return mi_heap_malloc_zero_aligned_at(mi_get_default_heap(),size,alignment,offset,zero);
|
||||
|
||||
void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false);
|
||||
}
|
||||
|
||||
void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heap_malloc_aligned_at(heap, size, alignment, 0);
|
||||
}
|
||||
|
||||
void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true);
|
||||
}
|
||||
|
||||
void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heap_zalloc_aligned_at(heap, size, alignment, 0);
|
||||
}
|
||||
|
||||
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 {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count, size, &total)) return NULL;
|
||||
return mi_heap_zalloc_aligned_at(heap, total, alignment, offset);
|
||||
}
|
||||
|
||||
void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heap_calloc_aligned_at(heap,count,size,alignment,0);
|
||||
}
|
||||
|
||||
void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_malloc_zero_aligned_at(size, alignment, offset, false);
|
||||
return mi_heap_malloc_aligned_at(mi_get_default_heap(), size, alignment, offset);
|
||||
}
|
||||
|
||||
void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_malloc_aligned_at(size, alignment, 0);
|
||||
return mi_heap_malloc_aligned(mi_get_default_heap(), size, alignment);
|
||||
}
|
||||
|
||||
void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_malloc_zero_aligned_at(size,alignment,offset,true);
|
||||
return mi_heap_zalloc_aligned_at(mi_get_default_heap(), size, alignment, offset);
|
||||
}
|
||||
|
||||
void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept {
|
||||
return mi_zalloc_aligned_at(size,alignment,0);
|
||||
return mi_heap_zalloc_aligned(mi_get_default_heap(), size, alignment);
|
||||
}
|
||||
|
||||
void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_zalloc_aligned_at(total,alignment,offset);
|
||||
return mi_heap_calloc_aligned_at(mi_get_default_heap(), count, size, alignment, offset);
|
||||
}
|
||||
|
||||
void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_zalloc_aligned(total,alignment);
|
||||
return mi_heap_calloc_aligned(mi_get_default_heap(), count, size, alignment);
|
||||
}
|
||||
|
||||
|
||||
static void* mi_realloc_zero_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {
|
||||
static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept {
|
||||
mi_assert(alignment > 0);
|
||||
if (alignment <= sizeof(uintptr_t)) return _mi_realloc_zero(p,newsize,zero);
|
||||
if (p == NULL) return mi_malloc_zero_aligned_at(newsize,alignment,offset,zero);
|
||||
if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero);
|
||||
if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero);
|
||||
size_t size = mi_usable_size(p);
|
||||
if (newsize <= size && newsize >= (size - (size / 2))
|
||||
&& (((uintptr_t)p + offset) % alignment) == 0) {
|
||||
return p; // reallocation still fits, is aligned and not more than 50% waste
|
||||
}
|
||||
else {
|
||||
void* newp = mi_malloc_aligned_at(newsize,alignment,offset);
|
||||
void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset);
|
||||
if (newp != NULL) {
|
||||
if (zero && newsize > size) {
|
||||
// also set last word in the previous allocation to zero to ensure any padding is zero-initialized
|
||||
@ -109,37 +128,25 @@ static void* mi_realloc_zero_aligned_at(void* p, size_t newsize, size_t alignmen
|
||||
}
|
||||
}
|
||||
|
||||
static void* _mi_realloc_aligned(void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept {
|
||||
static void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept {
|
||||
mi_assert(alignment > 0);
|
||||
if (alignment <= sizeof(uintptr_t)) return _mi_realloc_zero(p,newsize,zero);
|
||||
if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero);
|
||||
size_t offset = ((uintptr_t)p % alignment); // use offset of previous allocation (p can be NULL)
|
||||
return mi_realloc_zero_aligned_at(p,newsize,alignment,offset,zero);
|
||||
return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,zero);
|
||||
}
|
||||
|
||||
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_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false);
|
||||
}
|
||||
|
||||
void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false);
|
||||
}
|
||||
|
||||
void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_realloc_zero_aligned_at(p,newsize,alignment,offset,false);
|
||||
return mi_heap_realloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset);
|
||||
}
|
||||
|
||||
void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return _mi_realloc_aligned(p,newsize,alignment,false);
|
||||
}
|
||||
|
||||
void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
return mi_realloc_zero_aligned_at(p,newsize,alignment,offset,true);
|
||||
}
|
||||
|
||||
void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept {
|
||||
return _mi_realloc_aligned(p,newsize,alignment,true);
|
||||
}
|
||||
|
||||
void* mi_recalloc_aligned_at(void* p, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_rezalloc_aligned_at(p,total,alignment,offset);
|
||||
}
|
||||
|
||||
void* mi_recalloc_aligned(void* p, size_t count, size_t size, size_t alignment) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_rezalloc_aligned(p,total,alignment);
|
||||
return mi_heap_realloc_aligned(mi_get_default_heap(), p, newsize, alignment);
|
||||
}
|
||||
|
41
src/alloc.c
41
src/alloc.c
@ -344,13 +344,13 @@ void* mi_expand(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return p; // it fits
|
||||
}
|
||||
|
||||
void* _mi_realloc_zero(void* p, size_t newsize, bool zero) {
|
||||
if (p == NULL) return _mi_heap_malloc_zero(mi_get_default_heap(),newsize,zero);
|
||||
void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) {
|
||||
if (p == NULL) return _mi_heap_malloc_zero(heap,newsize,zero);
|
||||
size_t size = mi_usable_size(p);
|
||||
if (newsize <= size && newsize >= (size / 2)) {
|
||||
return p; // reallocation still fits and not more than 50% waste
|
||||
}
|
||||
void* newp = mi_malloc(newsize); // maybe in another heap
|
||||
void* newp = mi_heap_malloc(heap,newsize);
|
||||
if (mi_likely(newp != NULL)) {
|
||||
if (zero && newsize > size) {
|
||||
// also set last word in the previous allocation to zero to ensure any padding is zero-initialized
|
||||
@ -363,32 +363,41 @@ void* _mi_realloc_zero(void* p, size_t newsize, bool zero) {
|
||||
return newp;
|
||||
}
|
||||
|
||||
void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return _mi_realloc_zero(p,newsize,false);
|
||||
void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
|
||||
return _mi_heap_realloc_zero(heap, p, newsize, false);
|
||||
}
|
||||
|
||||
// Zero initialized reallocation
|
||||
void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return _mi_realloc_zero(p,newsize,true);
|
||||
void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count, size, &total)) return NULL;
|
||||
return mi_heap_realloc(heap, p, total);
|
||||
}
|
||||
|
||||
|
||||
// Reallocate but free `p` on errors
|
||||
void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
|
||||
void* newp = mi_heap_realloc(heap, p, newsize);
|
||||
if (newp==NULL && p!=NULL) mi_free(p);
|
||||
return newp;
|
||||
}
|
||||
|
||||
void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {
|
||||
return mi_heap_realloc(mi_get_default_heap(),p,newsize);
|
||||
}
|
||||
|
||||
void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_rezalloc(p,total);
|
||||
if (mi_mul_overflow(count, size, &total)) return NULL;
|
||||
return _mi_heap_realloc_zero(mi_get_default_heap(),p,total,true);
|
||||
}
|
||||
|
||||
void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {
|
||||
size_t total;
|
||||
if (mi_mul_overflow(count,size,&total)) return NULL;
|
||||
return mi_realloc(p,total);
|
||||
return mi_heap_reallocn(mi_get_default_heap(),p,count,size);
|
||||
}
|
||||
|
||||
// Reallocate but free `p` on errors
|
||||
void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept {
|
||||
void* newp = mi_realloc(p,newsize);
|
||||
if (newp==NULL && p!=NULL) mi_free(p);
|
||||
return newp;
|
||||
return mi_heap_reallocf(mi_get_default_heap(),p,newsize);
|
||||
}
|
||||
|
||||
// `strdup` using mi_malloc
|
||||
|
@ -12,6 +12,10 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
#include <ctype.h> // toupper
|
||||
#include <stdarg.h>
|
||||
|
||||
int mi_version(void) mi_attr_noexcept {
|
||||
return MI_MALLOC_VERSION;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Options
|
||||
// --------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user