@@ -6,9 +6,10 @@ terms of the MIT license. A copy of the license can be found in the file
66-----------------------------------------------------------------------------*/ 
77
88#include  "mimalloc.h" 
9- #include  "mimalloc-internal.h" 
9+ #include  "mimalloc/internal.h" 
10+ #include  "mimalloc/prim.h"   // mi_prim_get_default_heap 
1011
11- #include  <string.h>   // memset 
12+ #include  <string.h>       // memset 
1213
1314// ------------------------------------------------------ 
1415// Aligned Allocation 
@@ -61,52 +62,44 @@ static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t*
6162  mi_assert_internal (adjust  <  alignment );
6263  void *  aligned_p  =  (void * )((uintptr_t )p  +  adjust );
6364  if  (aligned_p  !=  p ) {
64-     mi_page_set_has_aligned (_mi_ptr_page (p ), true);
65+     mi_page_t *  page  =  _mi_ptr_page (p );
66+     mi_page_set_has_aligned (page , true);
67+     _mi_padding_shrink (page , (mi_block_t * )p , adjust  +  size );
6568  }
69+   // todo: expand padding if overallocated ? 
6670
6771  mi_assert_internal (mi_page_usable_block_size (_mi_ptr_page (p )) >= adjust  +  size );
6872  mi_assert_internal (p  ==  _mi_page_ptr_unalign (_mi_ptr_segment (aligned_p ), _mi_ptr_page (aligned_p ), aligned_p ));
6973  mi_assert_internal (((uintptr_t )aligned_p  +  offset ) % alignment  ==  0 );
70-   mi_assert_internal (mi_page_usable_block_size (_mi_ptr_page (p )) >= adjust  +  size );
74+   mi_assert_internal (mi_usable_size (aligned_p )>=size );
75+   mi_assert_internal (mi_usable_size (p ) ==  mi_usable_size (aligned_p )+ adjust );
7176
7277  // now zero the block if needed 
73-   if  (zero  &&  alignment  >  MI_ALIGNMENT_MAX ) {
74-     const  ptrdiff_t  diff  =  (uint8_t * )aligned_p  -  (uint8_t * )p ;
75-     const  ptrdiff_t  zsize  =  mi_page_usable_block_size (_mi_ptr_page (p )) -  diff  -  MI_PADDING_SIZE ;
76-     if  (zsize  >  0 ) { _mi_memzero (aligned_p , zsize ); }
78+   if  (alignment  >  MI_ALIGNMENT_MAX ) {
79+     // for the tracker, on huge aligned allocations only from the start of the large block is defined 
80+     mi_track_mem_undefined (aligned_p , size );
81+     if  (zero ) {
82+       _mi_memzero_aligned (aligned_p , mi_usable_size (aligned_p ));
83+     }
7784  }
7885
79-   #if  MI_TRACK_ENABLED 
8086  if  (p  !=  aligned_p ) {
81-     mi_track_free_size (p , oversize );
82-     mi_track_malloc (aligned_p , size , zero );
83-   }
84-   else  {
85-     mi_track_resize (aligned_p , oversize , size );
87+     mi_track_align (p ,aligned_p ,adjust ,mi_usable_size (aligned_p ));
8688  }
87-   #endif 
8889  return  aligned_p ;
8990}
9091
9192// Primitive aligned allocation 
9293static  void *  mi_heap_malloc_zero_aligned_at (mi_heap_t *  const  heap , const  size_t  size , const  size_t  alignment , const  size_t  offset , const  bool  zero ) mi_attr_noexcept 
9394{
9495  // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size. 
95-   mi_assert (alignment  >  0 );
9696  if  mi_unlikely (alignment  ==  0  ||  !_mi_is_power_of_two (alignment )) { // require power-of-two (see <https://en.cppreference.com/w/c/memory/aligned_alloc>) 
9797    #if  MI_DEBUG  >  0 
9898    _mi_error_message (EOVERFLOW , "aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\n" , size , alignment );
9999    #endif 
100100    return  NULL ;
101101  }
102-   /* 
103-   if mi_unlikely(alignment > MI_ALIGNMENT_MAX) {  // we cannot align at a boundary larger than this (or otherwise we cannot find segment headers) 
104-     #if MI_DEBUG > 0 
105-     _mi_error_message(EOVERFLOW, "aligned allocation has a maximum alignment of %zu (size %zu, alignment %zu)\n", MI_ALIGNMENT_MAX, size, alignment); 
106-     #endif 
107-     return NULL; 
108-   } 
109-   */ 
102+ 
110103  if  mi_unlikely (size  >  PTRDIFF_MAX ) {          // we don't allocate more than PTRDIFF_MAX (see <https://sourceware.org/ml/libc-announce/2019/msg00001.html>) 
111104    #if  MI_DEBUG  >  0 
112105    _mi_error_message (EOVERFLOW , "aligned allocation request is too large (size %zu, alignment %zu)\n" , size , alignment );
@@ -146,9 +139,9 @@ mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* he
146139}
147140
148141mi_decl_nodiscard  mi_decl_restrict  void *  mi_heap_malloc_aligned (mi_heap_t *  heap , size_t  size , size_t  alignment ) mi_attr_noexcept  {
142+   if  mi_unlikely (alignment  ==  0  ||  !_mi_is_power_of_two (alignment )) return  NULL ;
149143  #if  !MI_PADDING 
150144  // without padding, any small sized allocation is naturally aligned (see also `_mi_segment_page_start`) 
151-   if  (!_mi_is_power_of_two (alignment )) return  NULL ;
152145  if  mi_likely (_mi_is_power_of_two (size ) &&  size  >= alignment  &&  size  <= MI_SMALL_SIZE_MAX )
153146  #else 
154147  // with padding, we can only guarantee this for fixed alignments 
@@ -164,6 +157,11 @@ mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap,
164157  }
165158}
166159
160+ // ensure a definition is emitted 
161+ #if  defined(__cplusplus )
162+ static  void *  _mi_heap_malloc_aligned  =  (void * )& mi_heap_malloc_aligned ;
163+ #endif 
164+ 
167165// ------------------------------------------------------ 
168166// Aligned Allocation 
169167// ------------------------------------------------------ 
@@ -187,27 +185,27 @@ mi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap,
187185}
188186
189187mi_decl_nodiscard  mi_decl_restrict  void *  mi_malloc_aligned_at (size_t  size , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
190-   return  mi_heap_malloc_aligned_at (mi_get_default_heap (), size , alignment , offset );
188+   return  mi_heap_malloc_aligned_at (mi_prim_get_default_heap (), size , alignment , offset );
191189}
192190
193191mi_decl_nodiscard  mi_decl_restrict  void *  mi_malloc_aligned (size_t  size , size_t  alignment ) mi_attr_noexcept  {
194-   return  mi_heap_malloc_aligned (mi_get_default_heap (), size , alignment );
192+   return  mi_heap_malloc_aligned (mi_prim_get_default_heap (), size , alignment );
195193}
196194
197195mi_decl_nodiscard  mi_decl_restrict  void *  mi_zalloc_aligned_at (size_t  size , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
198-   return  mi_heap_zalloc_aligned_at (mi_get_default_heap (), size , alignment , offset );
196+   return  mi_heap_zalloc_aligned_at (mi_prim_get_default_heap (), size , alignment , offset );
199197}
200198
201199mi_decl_nodiscard  mi_decl_restrict  void *  mi_zalloc_aligned (size_t  size , size_t  alignment ) mi_attr_noexcept  {
202-   return  mi_heap_zalloc_aligned (mi_get_default_heap (), size , alignment );
200+   return  mi_heap_zalloc_aligned (mi_prim_get_default_heap (), size , alignment );
203201}
204202
205203mi_decl_nodiscard  mi_decl_restrict  void *  mi_calloc_aligned_at (size_t  count , size_t  size , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
206-   return  mi_heap_calloc_aligned_at (mi_get_default_heap (), count , size , alignment , offset );
204+   return  mi_heap_calloc_aligned_at (mi_prim_get_default_heap (), count , size , alignment , offset );
207205}
208206
209207mi_decl_nodiscard  mi_decl_restrict  void *  mi_calloc_aligned (size_t  count , size_t  size , size_t  alignment ) mi_attr_noexcept  {
210-   return  mi_heap_calloc_aligned (mi_get_default_heap (), count , size , alignment );
208+   return  mi_heap_calloc_aligned (mi_prim_get_default_heap (), count , size , alignment );
211209}
212210
213211
@@ -225,19 +223,13 @@ static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t ne
225223    return  p ;  // reallocation still fits, is aligned and not more than 50% waste 
226224  }
227225  else  {
226+     // note: we don't zero allocate upfront so we only zero initialize the expanded part 
228227    void *  newp  =  mi_heap_malloc_aligned_at (heap ,newsize ,alignment ,offset );
229228    if  (newp  !=  NULL ) {
230229      if  (zero  &&  newsize  >  size ) {
231- 	const  mi_page_t *  page  =  _mi_ptr_page (newp );
232- 	if  (page -> is_zero ) {
233- 	  // already zero initialized 
234- 	  mi_assert_expensive (mi_mem_is_zero (newp ,newsize ));
235- 	}
236- 	else  {
237- 	  // also set last word in the previous allocation to zero to ensure any padding is zero-initialized 
238- 	  size_t  start  =  (size  >= sizeof (intptr_t ) ? size  -  sizeof (intptr_t ) : 0 );
239- 	  memset ((uint8_t * )newp  +  start , 0 , newsize  -  start );
240- 	}
230+ 	// also set last word in the previous allocation to zero to ensure any padding is zero-initialized 
231+ 	size_t  start  =  (size  >= sizeof (intptr_t ) ? size  -  sizeof (intptr_t ) : 0 );
232+ 	_mi_memzero ((uint8_t * )newp  +  start , newsize  -  start );
241233      }
242234      _mi_memcpy_aligned (newp , p , (newsize  >  size  ? size  : newsize ));
243235      mi_free (p ); // only free if successful 
@@ -282,25 +274,25 @@ mi_decl_nodiscard void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_
282274}
283275
284276mi_decl_nodiscard  void *  mi_realloc_aligned_at (void *  p , size_t  newsize , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
285-   return  mi_heap_realloc_aligned_at (mi_get_default_heap (), p , newsize , alignment , offset );
277+   return  mi_heap_realloc_aligned_at (mi_prim_get_default_heap (), p , newsize , alignment , offset );
286278}
287279
288280mi_decl_nodiscard  void *  mi_realloc_aligned (void *  p , size_t  newsize , size_t  alignment ) mi_attr_noexcept  {
289-   return  mi_heap_realloc_aligned (mi_get_default_heap (), p , newsize , alignment );
281+   return  mi_heap_realloc_aligned (mi_prim_get_default_heap (), p , newsize , alignment );
290282}
291283
292284mi_decl_nodiscard  void *  mi_rezalloc_aligned_at (void *  p , size_t  newsize , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
293-   return  mi_heap_rezalloc_aligned_at (mi_get_default_heap (), p , newsize , alignment , offset );
285+   return  mi_heap_rezalloc_aligned_at (mi_prim_get_default_heap (), p , newsize , alignment , offset );
294286}
295287
296288mi_decl_nodiscard  void *  mi_rezalloc_aligned (void *  p , size_t  newsize , size_t  alignment ) mi_attr_noexcept  {
297-   return  mi_heap_rezalloc_aligned (mi_get_default_heap (), p , newsize , alignment );
289+   return  mi_heap_rezalloc_aligned (mi_prim_get_default_heap (), p , newsize , alignment );
298290}
299291
300292mi_decl_nodiscard  void *  mi_recalloc_aligned_at (void *  p , size_t  newcount , size_t  size , size_t  alignment , size_t  offset ) mi_attr_noexcept  {
301-   return  mi_heap_recalloc_aligned_at (mi_get_default_heap (), p , newcount , size , alignment , offset );
293+   return  mi_heap_recalloc_aligned_at (mi_prim_get_default_heap (), p , newcount , size , alignment , offset );
302294}
303295
304296mi_decl_nodiscard  void *  mi_recalloc_aligned (void *  p , size_t  newcount , size_t  size , size_t  alignment ) mi_attr_noexcept  {
305-   return  mi_heap_recalloc_aligned (mi_get_default_heap (), p , newcount , size , alignment );
297+   return  mi_heap_recalloc_aligned (mi_prim_get_default_heap (), p , newcount , size , alignment );
306298}
0 commit comments