mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-18 13:09:32 +03:00
Use builtin addition overflow checker
This adds wrappers for the __builtin add overflow checkers present in gcc 5+ and recent clang as well as fallback implementation for other compilers.
This commit is contained in:
parent
60e9d3f69d
commit
37da06298d
3 changed files with 21 additions and 4 deletions
|
@ -109,6 +109,9 @@ bool _mi_page_is_valid(mi_page_t* page);
|
|||
#define mi_likely(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define mi_decl_noinline __declspec(noinline)
|
||||
|
@ -146,6 +149,17 @@ static inline bool mi_mul_overflow(size_t size, size_t count, size_t* total) {
|
|||
&& size > 0 && (SIZE_MAX / size) < count);
|
||||
}
|
||||
|
||||
// Overflow detecting addition
|
||||
static inline bool mi_add_overflow(size_t a, size_t b, size_t* total) {
|
||||
#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5
|
||||
return __builtin_add_overflow(a, b, total);
|
||||
#else
|
||||
if (a >= (SIZE_MAX - b)) return true; // overflow
|
||||
*total = a + b;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Align a byte size to a size in _machine words_,
|
||||
// i.e. byte size == `wsize*sizeof(void*)`.
|
||||
static inline size_t _mi_wsize_from_size(size_t size) {
|
||||
|
|
|
@ -65,8 +65,10 @@ void* mi_valloc(size_t size) mi_attr_noexcept {
|
|||
|
||||
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;
|
||||
size_t asize;
|
||||
if (mi_unlikely(mi_add_overflow(size, psize, &asize)))
|
||||
return NULL; // overflow
|
||||
asize = ((asize - 1) / psize) * psize; // TODO: use _mi_align_down
|
||||
return mi_malloc_aligned(asize, psize);
|
||||
}
|
||||
|
||||
|
|
5
src/os.c
5
src/os.c
|
@ -302,8 +302,9 @@ static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit,
|
|||
// if not aligned, free it, overallocate, and unmap around it
|
||||
if (((uintptr_t)p % alignment != 0)) {
|
||||
mi_os_mem_free(p, size, stats);
|
||||
if (size >= (SIZE_MAX - alignment)) return NULL; // overflow
|
||||
size_t over_size = size + alignment;
|
||||
size_t over_size;
|
||||
if (mi_unlikely(mi_add_overflow(size, alignment, &over_size)))
|
||||
return NULL; // overflow
|
||||
|
||||
#if _WIN32
|
||||
// over-allocate and than re-allocate exactly at an aligned address in there.
|
||||
|
|
Loading…
Add table
Reference in a new issue