Skip to content

Commit 9e27e1c

Browse files
committed
improve rezalloc and rezalloc aligned, issue #763
1 parent 591e889 commit 9e27e1c

4 files changed

Lines changed: 38 additions & 35 deletions

File tree

include/mimalloc/internal.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ static inline bool _mi_is_aligned(void* p, size_t alignment) {
390390
// Align upwards
391391
static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {
392392
mi_assert_internal(alignment != 0);
393-
uintptr_t mask = alignment - 1;
393+
const uintptr_t mask = alignment - 1;
394394
if ((alignment & mask) == 0) { // power of two?
395395
return ((sz + mask) & ~mask);
396396
}
@@ -399,12 +399,27 @@ static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {
399399
}
400400
}
401401

402-
403402
// Align a pointer upwards
404403
static inline void* _mi_align_up_ptr(const void* p, size_t alignment) {
405404
return (void*)_mi_align_up((uintptr_t)p, alignment);
406405
}
407406

407+
// Align down
408+
static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
409+
mi_assert_internal(alignment != 0);
410+
const uintptr_t mask = alignment - 1;
411+
if ((alignment & mask) == 0) { // power of two?
412+
return (sz & ~mask);
413+
}
414+
else {
415+
return ((sz/alignment)*alignment);
416+
}
417+
}
418+
419+
// Align a pointer downwards
420+
static inline void* _mi_align_down_ptr(const void* p, size_t alignment) {
421+
return (void*)_mi_align_down((uintptr_t)p, alignment);
422+
}
408423

409424
// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`.
410425
static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) {

src/alloc-aligned.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,17 +301,18 @@ static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t ne
301301
return p; // reallocation still fits, is aligned and not more than 50% waste
302302
}
303303
else {
304-
// note: we don't zero allocate upfront so we only zero initialize the expanded part
304+
// note: we don't zero allocate upfront so we only zero initialize the expanded part (at the cost of calling mi_usable_size)
305305
void* const newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset);
306306
if (newp != NULL) {
307-
const size_t usable = mi_usable_size(newp);
307+
const size_t copy_size = (newsize > size ? size : newsize);
308+
const size_t zero_start = (copy_size >= sizeof(intptr_t) ? copy_size - sizeof(intptr_t) : 0); // also set last word in the previous allocation to zero to ensure any padding is zero-initialized
309+
const size_t usable = mi_usable_size(newp);
308310
mi_assert_internal(usable >= newsize); // use usable for zero'ing, issue #763
309-
if (zero && usable > size) {
311+
if (zero && usable > zero_start) {
310312
// also set last word in the previous allocation to zero to ensure any padding is zero-initialized
311-
const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);
312-
_mi_memzero((uint8_t*)newp + start, usable - start);
313+
_mi_memzero((uint8_t*)newp + zero_start, usable - zero_start);
313314
}
314-
_mi_memcpy(newp, p, (newsize > size ? size : newsize)); // cannot be aligned due to abitrary offset... (todo: require offset to be a multiple of sizeof(void*)?)
315+
_mi_memcpy(newp, p, copy_size); // cannot be aligned due to abitrary offset... (todo: require offset to be a multiple of sizeof(void*)?)
315316
mi_free(p); // only free if successful
316317
}
317318
return newp;

src/alloc.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -310,23 +310,26 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero,
310310
if (usable_post!=NULL) { *usable_post = mi_page_usable_block_size(page); }
311311
return p; // reallocation still fits and not more than 50% waste
312312
}
313-
// note: we don't zero allocate upfront so we only zero initialize the expanded part
314-
void* const newp = mi_heap_umalloc(heap,newsize,usable_post);
313+
// note: we don't zero allocate upfront so we only zero initialize the expanded part
314+
size_t usable; // use usable for zero-ing, issue #763
315+
void* const newp = mi_heap_umalloc(heap,newsize,&usable);
316+
if (usable_post!=NULL) { *usable_post = usable; }
315317
if mi_likely(newp != NULL) {
316-
const size_t usable = mi_usable_size(newp);
317-
mi_assert_internal(usable >= newsize); // use usable for zero-ing, issue #763
318-
if (zero && usable > size) {
319-
// also set last word in the previous allocation to zero to ensure any padding is zero-initialized
320-
const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);
321-
_mi_memzero((uint8_t*)newp + start, usable - start);
318+
const size_t copy_size = (newsize > size ? size : newsize);
319+
const size_t zero_start = _mi_align_down( (copy_size >= sizeof(intptr_t) ? copy_size - sizeof(intptr_t) : 0), sizeof(intptr_t)); // also set last word in the previous allocation to zero to ensure any padding is zero-initialized
320+
#if MI_PADDING
321+
usable = mi_usable_size(newp); // avoid zero'ing padding
322+
#endif
323+
mi_assert_internal(usable >= newsize);
324+
if (zero && usable > zero_start) {
325+
_mi_memzero_aligned((uint8_t*)newp + zero_start, usable - zero_start);
322326
}
323327
else if (newsize == 0) {
324328
((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725)
325329
}
326330
if mi_likely(p != NULL) {
327-
const size_t copysize = (newsize > size ? size : newsize);
328-
mi_track_mem_defined(p,copysize); // _mi_useable_size may be too large for byte precise memory tracking..
329-
_mi_memcpy(newp, p, copysize);
331+
mi_track_mem_defined(p,copy_size); // _mi_useable_size may be too large for byte precise memory tracking..
332+
_mi_memcpy_aligned(newp, p, copy_size);
330333
mi_free(p); // only free the original pointer if successful
331334
}
332335
}

src/os.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,6 @@ void _mi_os_init(void) {
9191
bool _mi_os_decommit(void* addr, size_t size);
9292
bool _mi_os_commit(void* addr, size_t size, bool* is_zero);
9393

94-
static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
95-
mi_assert_internal(alignment != 0);
96-
uintptr_t mask = alignment - 1;
97-
if ((alignment & mask) == 0) { // power of two?
98-
return (sz & ~mask);
99-
}
100-
else {
101-
return ((sz / alignment) * alignment);
102-
}
103-
}
104-
105-
static void* _mi_align_down_ptr(void* p, size_t alignment) {
106-
return (void*)_mi_align_down((uintptr_t)p, alignment);
107-
}
108-
109-
11094
/* -----------------------------------------------------------
11195
aligned hinting
11296
-------------------------------------------------------------- */

0 commit comments

Comments
 (0)