Skip to content

Commit 27d7daa

Browse files
authored
Update mimalloc to 2.1.7 (#21548)
1 parent 6ec67f9 commit 27d7daa

34 files changed

+2342
-1655
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ See docs/process.md for more on how version tagging works.
2121
3.1.73 (in development)
2222
-----------------------
2323
- libunwind was updated to LLVM 19.1.4. (#22394)
24+
- mimalloc was updated to 2.1.7. (#21548)
2425

2526
3.1.72 - 11/19/24
2627
-----------------

system/lib/mimalloc/README.emscripten

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

2-
This contains mimalloc 4e50d6714d471b72b2285e25a3df6c92db944593 with
3-
Emscripten backend additions.
2+
This contains mimalloc 8c532c32c3c96e5ba1f2283e032f69ead8add00f (v2.1.7) with
3+
Emscripten-specific changes.
44

55
Origin: https://github.com/microsoft/mimalloc
66

system/lib/mimalloc/include/mimalloc-override.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ not accidentally mix pointers from different allocators).
2424
#define free(p) mi_free(p)
2525

2626
#define strdup(s) mi_strdup(s)
27-
#define strndup(s,n) mi_strndup(s,n)
27+
#define strndup(s,n) mi_strndup(s,n)
2828
#define realpath(f,n) mi_realpath(f,n)
2929

3030
// Microsoft extensions
@@ -43,6 +43,7 @@ not accidentally mix pointers from different allocators).
4343
#define reallocf(p,n) mi_reallocf(p,n)
4444
#define malloc_size(p) mi_usable_size(p)
4545
#define malloc_usable_size(p) mi_usable_size(p)
46+
#define malloc_good_size(sz) mi_malloc_good_size(sz)
4647
#define cfree(p) mi_free(p)
4748

4849
#define valloc(n) mi_valloc(n)

system/lib/mimalloc/include/mimalloc.h

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ terms of the MIT license. A copy of the license can be found in the file
88
#ifndef MIMALLOC_H
99
#define MIMALLOC_H
1010

11-
#define MI_MALLOC_VERSION 212 // major + 2 digits minor
11+
#define MI_MALLOC_VERSION 217 // major + 2 digits minor
1212

1313
// ------------------------------------------------------
1414
// Compiler specific attributes
@@ -275,7 +275,7 @@ mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size
275275
mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;
276276
mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept;
277277

278-
mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept;
278+
mi_decl_export void mi_debug_show_arenas(bool show_inuse, bool show_abandoned, bool show_purge) mi_attr_noexcept;
279279

280280
// Experimental: heaps associated with specific memory arena's
281281
typedef int mi_arena_id_t;
@@ -318,40 +318,44 @@ mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size
318318

319319
typedef enum mi_option_e {
320320
// stable options
321-
mi_option_show_errors, // print error messages
322-
mi_option_show_stats, // print statistics on termination
323-
mi_option_verbose, // print verbose messages
324-
// the following options are experimental (see src/options.h)
325-
mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1)
326-
mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2)
327-
mi_option_purge_decommits, // should a memory purge decommit (or only reset) (=1)
328-
mi_option_allow_large_os_pages, // allow large (2MiB) OS pages, implies eager commit
329-
mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB/page) at startup
330-
mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node
331-
mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup
321+
mi_option_show_errors, // print error messages
322+
mi_option_show_stats, // print statistics on termination
323+
mi_option_verbose, // print verbose messages
324+
// advanced options
325+
mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1)
326+
mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2)
327+
mi_option_purge_decommits, // should a memory purge decommit? (=1). Set to 0 to use memory reset on a purge (instead of decommit)
328+
mi_option_allow_large_os_pages, // allow large (2 or 4 MiB) OS pages, implies eager commit. If false, also disables THP for the process.
329+
mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB pages) at startup
330+
mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node
331+
mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup (internally, this value is in KiB; use `mi_option_get_size`)
332332
mi_option_deprecated_segment_cache,
333333
mi_option_deprecated_page_reset,
334-
mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination
334+
mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination
335335
mi_option_deprecated_segment_reset,
336-
mi_option_eager_commit_delay,
337-
mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all.
338-
mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes.
339-
mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas)
340-
mi_option_os_tag, // tag used for OS logging (macOS only for now)
341-
mi_option_max_errors, // issue at most N error messages
342-
mi_option_max_warnings, // issue at most N warning messages
343-
mi_option_max_segment_reclaim,
344-
mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe.
345-
mi_option_arena_reserve, // initial memory size in KiB for arena reservation (1GiB on 64-bit)
346-
mi_option_arena_purge_mult,
336+
mi_option_eager_commit_delay, // the first N segments per thread are not eagerly committed (but per page in the segment on demand)
337+
mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. (=10)
338+
mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes.
339+
mi_option_disallow_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas)
340+
mi_option_os_tag, // tag used for OS logging (macOS only for now) (=100)
341+
mi_option_max_errors, // issue at most N error messages
342+
mi_option_max_warnings, // issue at most N warning messages
343+
mi_option_max_segment_reclaim, // max. percentage of the abandoned segments can be reclaimed per try (=10%)
344+
mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe
345+
mi_option_arena_reserve, // initial memory size for arena reservation (= 1 GiB on 64-bit) (internally, this value is in KiB; use `mi_option_get_size`)
346+
mi_option_arena_purge_mult, // multiplier for `purge_delay` for the purging delay for arenas (=10)
347347
mi_option_purge_extend_delay,
348+
mi_option_abandoned_reclaim_on_free, // allow to reclaim an abandoned segment on a free (=1)
349+
mi_option_disallow_arena_alloc, // 1 = do not use arena's for allocation (except if using specific arena id's)
350+
mi_option_retry_on_oom, // retry on out-of-memory for N milli seconds (=400), set to 0 to disable retries. (only on windows)
348351
_mi_option_last,
349352
// legacy option names
350353
mi_option_large_os_pages = mi_option_allow_large_os_pages,
351354
mi_option_eager_region_commit = mi_option_arena_eager_commit,
352355
mi_option_reset_decommits = mi_option_purge_decommits,
353356
mi_option_reset_delay = mi_option_purge_delay,
354-
mi_option_abandoned_page_reset = mi_option_abandoned_page_purge
357+
mi_option_abandoned_page_reset = mi_option_abandoned_page_purge,
358+
mi_option_limit_os_alloc = mi_option_disallow_os_alloc
355359
} mi_option_t;
356360

357361

@@ -494,7 +498,7 @@ template<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : publi
494498
using typename _mi_stl_allocator_common<T>::value_type;
495499
using typename _mi_stl_allocator_common<T>::pointer;
496500

497-
_mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp) { } /* will not delete nor destroy the passed in heap */
501+
_mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp, [](mi_heap_t*) {}) {} /* will not delete nor destroy the passed in heap */
498502

499503
#if (__cplusplus >= 201703L) // C++17
500504
mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); }
@@ -513,7 +517,7 @@ template<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : publi
513517
protected:
514518
std::shared_ptr<mi_heap_t> heap;
515519
template<class U, bool D> friend struct _mi_heap_stl_allocator_common;
516-
520+
517521
_mi_heap_stl_allocator_common() {
518522
mi_heap_t* hp = mi_heap_new();
519523
this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete)); /* calls heap_delete/destroy when the refcount drops to zero */
@@ -530,7 +534,7 @@ template<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : publi
530534
template<class T> struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common<T, false> {
531535
using typename _mi_heap_stl_allocator_common<T, false>::size_type;
532536
mi_heap_stl_allocator() : _mi_heap_stl_allocator_common<T, false>() { } // creates fresh heap that is deleted when the destructor is called
533-
mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { } // no delete nor destroy on the passed in heap
537+
mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { } // no delete nor destroy on the passed in heap
534538
template<class U> mi_heap_stl_allocator(const mi_heap_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, false>(x) { }
535539

536540
mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; }
@@ -547,7 +551,7 @@ template<class T1, class T2> bool operator!=(const mi_heap_stl_allocator<T1>& x,
547551
template<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common<T, true> {
548552
using typename _mi_heap_stl_allocator_common<T, true>::size_type;
549553
mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common<T, true>() { } // creates fresh heap that is destroyed when the destructor is called
550-
mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { } // no delete nor destroy on the passed in heap
554+
mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { } // no delete nor destroy on the passed in heap
551555
template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }
552556

553557
mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }

system/lib/mimalloc/include/mimalloc/atomic.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ terms of the MIT license. A copy of the license can be found in the file
2323
#define _Atomic(tp) std::atomic<tp>
2424
#define mi_atomic(name) std::atomic_##name
2525
#define mi_memory_order(name) std::memory_order_##name
26-
#if !defined(ATOMIC_VAR_INIT) || (__cplusplus >= 202002L) // c++20, see issue #571
27-
#define MI_ATOMIC_VAR_INIT(x) x
26+
#if (__cplusplus >= 202002L) // c++20, see issue #571
27+
#define MI_ATOMIC_VAR_INIT(x) x
28+
#elif !defined(ATOMIC_VAR_INIT)
29+
#define MI_ATOMIC_VAR_INIT(x) x
2830
#else
2931
#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
3032
#endif
@@ -39,7 +41,9 @@ terms of the MIT license. A copy of the license can be found in the file
3941
#include <stdatomic.h>
4042
#define mi_atomic(name) atomic_##name
4143
#define mi_memory_order(name) memory_order_##name
42-
#if !defined(ATOMIC_VAR_INIT) || (__STDC_VERSION__ >= 201710L) // c17, see issue #735
44+
#if (__STDC_VERSION__ >= 201710L) // c17, see issue #735
45+
#define MI_ATOMIC_VAR_INIT(x) x
46+
#elif !defined(ATOMIC_VAR_INIT)
4347
#define MI_ATOMIC_VAR_INIT(x) x
4448
#else
4549
#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
@@ -128,8 +132,10 @@ static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) {
128132

129133
#elif defined(_MSC_VER)
130134

131-
// MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics.
135+
// Legacy MSVC plain C compilation wrapper that uses Interlocked operations to model C11 atomics.
136+
#ifndef WIN32_LEAN_AND_MEAN
132137
#define WIN32_LEAN_AND_MEAN
138+
#endif
133139
#include <windows.h>
134140
#include <intrin.h>
135141
#ifdef _WIN64
@@ -195,7 +201,7 @@ static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_
195201
#else
196202
uintptr_t x = *p;
197203
if (mo > mi_memory_order_relaxed) {
198-
while (!mi_atomic_compare_exchange_weak_explicit(p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
204+
while (!mi_atomic_compare_exchange_weak_explicit((_Atomic(uintptr_t)*)p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
199205
}
200206
return x;
201207
#endif
@@ -323,7 +329,9 @@ static inline void mi_atomic_yield(void) {
323329
std::this_thread::yield();
324330
}
325331
#elif defined(_WIN32)
332+
#ifndef WIN32_LEAN_AND_MEAN
326333
#define WIN32_LEAN_AND_MEAN
334+
#endif
327335
#include <windows.h>
328336
static inline void mi_atomic_yield(void) {
329337
YieldProcessor();

0 commit comments

Comments
 (0)