Skip to content

Commit 9cdc478

Browse files
authored
Update mimalloc to v2.1.2 (git-for-windows#4740)
The mimalloc project [has released a couple versions](https://github.com/microsoft/mimalloc?tab=readme-ov-file#releases) since we last integrated it into Git for Windows. Let's take the most recent one. This PR is structured in the following way: 1. Revert all mimalloc commits, in reverse chronological order (newest first), marking them as `fixup!`s of the reverted commits. 2. Import (a subset of) mimalloc v2.1.2, marking it as an `amend!` of the commit that originally imported mimalloc. 3. Replay the remaining mimalloc commits, in chronological order, marking them as `fixup!`s of the original commits.
2 parents a0e4621 + 1475d9f commit 9cdc478

25 files changed

+3055
-3757
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -2088,8 +2088,10 @@ ifdef USE_MIMALLOC
20882088
compat/mimalloc/os.o \
20892089
compat/mimalloc/page.o \
20902090
compat/mimalloc/random.o \
2091+
compat/mimalloc/prim/windows/prim.o \
20912092
compat/mimalloc/segment.o \
20922093
compat/mimalloc/segment-cache.o \
2094+
compat/mimalloc/segment-map.o \
20932095
compat/mimalloc/stats.o
20942096

20952097
COMPAT_CFLAGS += -Icompat/mimalloc -DMI_DEBUG=0 -DUSE_MIMALLOC --std=gnu11

compat/mimalloc/alloc-aligned.c

+39-47
Original file line numberDiff line numberDiff line change
@@ -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
9293
static 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

148141
mi_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

189187
mi_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

193191
mi_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

197195
mi_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

201199
mi_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

205203
mi_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

209207
mi_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

284276
mi_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

288280
mi_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

292284
mi_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

296288
mi_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

300292
mi_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

304296
mi_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

Comments
 (0)