diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/alloc-inl.h | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 11c1143a..b8c83db4 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -767,6 +767,20 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func, #endif /* _WANT_ORIGINAL_AFL_ALLOC */ +/* This function calculates the lowest power of 2 greater or equal its argument. + @return The rounded up power of 2 (if no overflow) or 0 on overflow. +*/ +static inline size_t powerOf2Ceil(size_t in) { + if (in == 0 || in > (size_t)-1) return 0; /* avoid undefined behaviour under-/overflow */ + size_t out = in - 1; + out |= out >> 1; + out |= out >> 2; + out |= out >> 4; + out |= out >> 8; + out |= out >> 16; + return out + 1; +} + /* This function makes sure *size is > size_needed after call. It will realloc *buf otherwise. *size will grow exponentially as per: @@ -784,16 +798,19 @@ static inline void *ck_maybe_grow(void **buf, size_t *size, if (likely(*size >= size_needed)) return *buf; /* No initial size was set */ - if (*size == 0) *size = INITIAL_GROWTH_SIZE; - while (*size < size_needed) { + if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE; - /* in case of overflow we'll realloc to size_needed */ - if (2*(*size) < size_needed) *size = size_needed; - else *size *= 2; + /* grow exponentially */ + size_t next_size = powerOf2Ceil(size_needed); + /* handle overflow */ + if (!next_size) { + next_size = size_needed; } - *buf = ck_realloc(*buf, *size); + /* alloc */ + *buf = ck_realloc(*buf, next_size); + *size = next_size; return *buf; |