@shd101wyy/yo 0.1.24 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +30 -0
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +436 -2
- package/out/cjs/index.cjs +551 -553
- package/out/cjs/yo-cli.cjs +638 -632
- package/out/cjs/yo-lsp.cjs +595 -597
- package/out/esm/index.mjs +487 -489
- package/out/types/src/codegen/utils/index.d.ts +1 -0
- package/out/types/src/expr.d.ts +1 -0
- package/out/types/src/test-runner.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/vendor/mimalloc/.github/workflows/release.yaml +55 -0
- package/vendor/mimalloc/.github/workflows/stale.yaml +27 -0
- package/vendor/mimalloc/.github/workflows/test.yaml +163 -0
- package/vendor/mimalloc/CMakeLists.txt +52 -33
- package/vendor/mimalloc/azure-pipelines.yml +4 -3
- package/vendor/mimalloc/bin/bundle.bat +74 -0
- package/vendor/mimalloc/bin/bundle.sh +232 -0
- package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +2 -2
- package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +2 -2
- package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +1 -1
- package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +4 -3
- package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +1 -1
- package/vendor/mimalloc/doc/mimalloc-doc.h +42 -4
- package/vendor/mimalloc/doc/release-notes.md +15 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +3 -3
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj +511 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj.filters +117 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-dep.vcxproj +360 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-override-static.vcxproj +310 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc.sln +92 -35
- package/vendor/mimalloc/include/mimalloc/atomic.h +178 -182
- package/vendor/mimalloc/include/mimalloc/bits.h +8 -10
- package/vendor/mimalloc/include/mimalloc/internal.h +76 -32
- package/vendor/mimalloc/include/mimalloc/prim.h +25 -18
- package/vendor/mimalloc/include/mimalloc/track.h +7 -2
- package/vendor/mimalloc/include/mimalloc/types.h +57 -29
- package/vendor/mimalloc/include/mimalloc-override.h +10 -10
- package/vendor/mimalloc/include/mimalloc-stats.h +18 -6
- package/vendor/mimalloc/include/mimalloc.h +22 -12
- package/vendor/mimalloc/readme.md +42 -17
- package/vendor/mimalloc/src/alloc-aligned.c +13 -11
- package/vendor/mimalloc/src/alloc-override.c +97 -17
- package/vendor/mimalloc/src/alloc-posix.c +44 -27
- package/vendor/mimalloc/src/alloc.c +73 -23
- package/vendor/mimalloc/src/arena-meta.c +3 -3
- package/vendor/mimalloc/src/arena.c +380 -192
- package/vendor/mimalloc/src/bitmap.c +68 -18
- package/vendor/mimalloc/src/bitmap.h +8 -4
- package/vendor/mimalloc/src/free.c +83 -47
- package/vendor/mimalloc/src/heap.c +94 -40
- package/vendor/mimalloc/src/init.c +273 -102
- package/vendor/mimalloc/src/libc.c +53 -8
- package/vendor/mimalloc/src/options.c +43 -40
- package/vendor/mimalloc/src/os.c +110 -45
- package/vendor/mimalloc/src/page-map.c +14 -8
- package/vendor/mimalloc/src/page-queue.c +9 -6
- package/vendor/mimalloc/src/page.c +26 -16
- package/vendor/mimalloc/src/prim/emscripten/prim.c +10 -1
- package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +35 -16
- package/vendor/mimalloc/src/prim/unix/prim.c +26 -22
- package/vendor/mimalloc/src/prim/wasi/prim.c +7 -4
- package/vendor/mimalloc/src/prim/windows/prim.c +247 -44
- package/vendor/mimalloc/src/random.c +8 -3
- package/vendor/mimalloc/src/stats.c +59 -48
- package/vendor/mimalloc/src/theap.c +85 -44
- package/vendor/mimalloc/src/threadlocal.c +102 -41
- package/vendor/mimalloc/test/main-override-static.c +31 -2
- package/vendor/mimalloc/test/main-override.c +27 -14
- package/vendor/mimalloc/test/main-static-dep.cpp +46 -0
- package/vendor/mimalloc/test/main-static-dep.h +11 -0
- package/vendor/mimalloc/test/test-api-fill.c +2 -2
- package/vendor/mimalloc/test/test-stress.c +3 -3
- package/vendor/mimalloc/test/test-wrong.c +11 -7
|
@@ -131,6 +131,7 @@ void _mi_strlcat(char* dest, const char* src, size_t dest_size);
|
|
|
131
131
|
size_t _mi_strlen(const char* s);
|
|
132
132
|
size_t _mi_strnlen(const char* s, size_t max_len);
|
|
133
133
|
char* _mi_strnstr(char* s, size_t max_len, const char* pat);
|
|
134
|
+
bool _mi_streq(const char* s, const char* t);
|
|
134
135
|
bool _mi_getenv(const char* name, char* result, size_t result_size);
|
|
135
136
|
|
|
136
137
|
// "options.c"
|
|
@@ -175,10 +176,12 @@ mi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id);
|
|
|
175
176
|
mi_threadid_t _mi_thread_id(void) mi_attr_noexcept;
|
|
176
177
|
size_t _mi_thread_seq_id(void) mi_attr_noexcept;
|
|
177
178
|
bool _mi_is_heap_main(const mi_heap_t* heap);
|
|
179
|
+
bool _mi_is_theap_main(const mi_theap_t* theap);
|
|
178
180
|
void _mi_theap_guarded_init(mi_theap_t* theap);
|
|
179
181
|
void _mi_theap_options_init(mi_theap_t* theap);
|
|
180
182
|
mi_theap_t* _mi_theap_default_safe(void); // ensure the returned theap is initialized
|
|
181
|
-
|
|
183
|
+
mi_theap_t* _mi_theap_main_safe(void);
|
|
184
|
+
|
|
182
185
|
// os.c
|
|
183
186
|
void _mi_os_init(void); // called from process init
|
|
184
187
|
void* _mi_os_alloc(size_t size, mi_memid_t* memid);
|
|
@@ -284,13 +287,16 @@ size_t _mi_bin(size_t size); // for stats
|
|
|
284
287
|
|
|
285
288
|
// "theap.c"
|
|
286
289
|
mi_theap_t* _mi_theap_create(mi_heap_t* heap, mi_tld_t* tld);
|
|
287
|
-
void _mi_theap_delete(mi_theap_t* theap);
|
|
290
|
+
void _mi_theap_delete(mi_theap_t* theap, bool acquire_tld_theaps_lock);
|
|
288
291
|
void _mi_theap_default_set(mi_theap_t* theap);
|
|
289
292
|
void _mi_theap_cached_set(mi_theap_t* theap);
|
|
290
293
|
void _mi_theap_collect_retired(mi_theap_t* theap, bool force);
|
|
294
|
+
void _mi_theap_collect_abandon(mi_theap_t* theap);
|
|
291
295
|
bool _mi_theap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg);
|
|
292
296
|
void _mi_theap_page_reclaim(mi_theap_t* theap, mi_page_t* page);
|
|
293
|
-
|
|
297
|
+
bool _mi_theap_free(mi_theap_t* theap, bool acquire_heap_theaps_lock, bool acquire_tld_theaps_lock);
|
|
298
|
+
void _mi_theap_incref(mi_theap_t* theap);
|
|
299
|
+
void _mi_theap_decref(mi_theap_t* theap);
|
|
294
300
|
|
|
295
301
|
// "heap.c"
|
|
296
302
|
void _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);
|
|
@@ -298,7 +304,7 @@ mi_decl_cold mi_theap_t* _mi_heap_theap_get_or_init(const mi_heap_t* heap); //
|
|
|
298
304
|
mi_decl_cold mi_theap_t* _mi_heap_theap_get_peek(const mi_heap_t* heap); // get the theap for a heap without initializing (and return NULL in that case)
|
|
299
305
|
void _mi_heap_move_pages(mi_heap_t* heap_from, mi_heap_t* heap_to); // in "arena.c"
|
|
300
306
|
void _mi_heap_destroy_pages(mi_heap_t* heap_from); // in "arena.c"
|
|
301
|
-
|
|
307
|
+
void _mi_heap_force_destroy(mi_heap_t* heap); // allow destroying the main heap
|
|
302
308
|
|
|
303
309
|
// "stats.c"
|
|
304
310
|
void _mi_stats_init(void);
|
|
@@ -412,7 +418,7 @@ typedef struct mi_option_desc_s {
|
|
|
412
418
|
Inlined definitions
|
|
413
419
|
----------------------------------------------------------- */
|
|
414
420
|
#define MI_UNUSED(x) (void)(x)
|
|
415
|
-
#
|
|
421
|
+
#if (MI_DEBUG>1)
|
|
416
422
|
#define MI_UNUSED_RELEASE(x)
|
|
417
423
|
#else
|
|
418
424
|
#define MI_UNUSED_RELEASE(x) MI_UNUSED(x)
|
|
@@ -428,6 +434,7 @@ typedef struct mi_option_desc_s {
|
|
|
428
434
|
|
|
429
435
|
#define MI_INIT74(x) MI_INIT64(x),MI_INIT8(x),x(),x()
|
|
430
436
|
#define MI_INIT5(x) MI_INIT4(x),x()
|
|
437
|
+
#define MI_INIT6(x) MI_INIT4(x),x(),x()
|
|
431
438
|
|
|
432
439
|
#include <string.h>
|
|
433
440
|
// initialize a local variable to zero; use memset as compilers optimize constant sized memset's
|
|
@@ -439,9 +446,8 @@ static inline bool _mi_is_power_of_two(uintptr_t x) {
|
|
|
439
446
|
}
|
|
440
447
|
|
|
441
448
|
// Is a pointer aligned?
|
|
442
|
-
static inline bool _mi_is_aligned(void* p, size_t alignment) {
|
|
443
|
-
|
|
444
|
-
return (((uintptr_t)p % alignment) == 0);
|
|
449
|
+
static inline bool _mi_is_aligned(const void* p, size_t alignment) {
|
|
450
|
+
return (alignment==0 || ((uintptr_t)p % alignment) == 0);
|
|
445
451
|
}
|
|
446
452
|
|
|
447
453
|
// Align upwards
|
|
@@ -456,13 +462,11 @@ static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {
|
|
|
456
462
|
}
|
|
457
463
|
}
|
|
458
464
|
|
|
459
|
-
|
|
460
465
|
// Align a pointer upwards
|
|
461
|
-
static inline
|
|
462
|
-
return (
|
|
466
|
+
static inline void* _mi_align_up_ptr(const void* p, size_t alignment) {
|
|
467
|
+
return (void*)_mi_align_up((uintptr_t)p, alignment);
|
|
463
468
|
}
|
|
464
469
|
|
|
465
|
-
|
|
466
470
|
static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
|
|
467
471
|
mi_assert_internal(alignment != 0);
|
|
468
472
|
uintptr_t mask = alignment - 1;
|
|
@@ -474,7 +478,8 @@ static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
|
|
|
474
478
|
}
|
|
475
479
|
}
|
|
476
480
|
|
|
477
|
-
|
|
481
|
+
// align a pointer downwards
|
|
482
|
+
static inline void* _mi_align_down_ptr(const void* p, size_t alignment) {
|
|
478
483
|
return (void*)_mi_align_down((uintptr_t)p, alignment);
|
|
479
484
|
}
|
|
480
485
|
|
|
@@ -560,8 +565,13 @@ static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* tot
|
|
|
560
565
|
extern mi_decl_hidden const mi_theap_t _mi_theap_empty; // read-only empty theap, initial value of the thread local default theap (in the MI_TLS_MODEL_THREAD_LOCAL)
|
|
561
566
|
extern mi_decl_hidden const mi_theap_t _mi_theap_empty_wrong; // read-only empty theap used to signal that a theap for a heap could not be allocated
|
|
562
567
|
|
|
568
|
+
|
|
569
|
+
static inline mi_heap_t* _mi_theap_heap(const mi_theap_t* theap) {
|
|
570
|
+
return mi_atomic_load_ptr_acquire(mi_heap_t,&theap->heap);
|
|
571
|
+
}
|
|
572
|
+
|
|
563
573
|
static inline bool mi_theap_is_initialized(const mi_theap_t* theap) {
|
|
564
|
-
return (theap != NULL && theap
|
|
574
|
+
return (theap != NULL && _mi_theap_heap(theap) != NULL);
|
|
565
575
|
}
|
|
566
576
|
|
|
567
577
|
static inline mi_page_t* _mi_theap_get_free_small_page(mi_theap_t* theap, size_t size) {
|
|
@@ -709,19 +719,35 @@ static inline size_t mi_page_usable_block_size(const mi_page_t* page) {
|
|
|
709
719
|
return mi_page_block_size(page) - MI_PADDING_SIZE;
|
|
710
720
|
}
|
|
711
721
|
|
|
712
|
-
|
|
722
|
+
static inline bool mi_page_meta_is_separated(const mi_page_t* page) {
|
|
723
|
+
#if MI_PAGE_META_IS_SEPARATED
|
|
724
|
+
// usually separated but can still be in front for direct OS allocations (due to size or alignment) or due to MI_PAGE_META_ALIGNED_FREE_SMALL
|
|
725
|
+
return (page->memid.memkind == MI_MEM_ARENA && page != _mi_align_down_ptr(page->page_start, MI_ARENA_SLICE_ALIGN));
|
|
726
|
+
#else
|
|
727
|
+
MI_UNUSED(page);
|
|
728
|
+
return false;
|
|
729
|
+
#endif
|
|
730
|
+
}
|
|
731
|
+
|
|
713
732
|
static inline uint8_t* mi_page_slice_start(const mi_page_t* page) {
|
|
714
|
-
|
|
733
|
+
if (mi_page_meta_is_separated(page)) {
|
|
734
|
+
// page meta info is at a separate location (at `arena->pages`)
|
|
735
|
+
return (uint8_t*)_mi_align_down_ptr(page->page_start, MI_ARENA_SLICE_ALIGN);
|
|
736
|
+
}
|
|
737
|
+
else {
|
|
738
|
+
// page meta info is at the start of the page slices
|
|
739
|
+
return (uint8_t*)page;
|
|
740
|
+
}
|
|
715
741
|
}
|
|
716
742
|
|
|
717
|
-
// This gives the offset relative to the start slice of a page.
|
|
718
|
-
// locate page info outside the page-data itself.
|
|
743
|
+
// This gives the offset relative to the start slice of a page.
|
|
719
744
|
static inline size_t mi_page_slice_offset_of(const mi_page_t* page, size_t offset_relative_to_page_start) {
|
|
720
745
|
return (page->page_start - mi_page_slice_start(page)) + offset_relative_to_page_start;
|
|
721
746
|
}
|
|
722
747
|
|
|
748
|
+
// Currently committed part of a page
|
|
723
749
|
static inline size_t mi_page_committed(const mi_page_t* page) {
|
|
724
|
-
return (page->slice_committed == 0 ? mi_page_size(page) : page->slice_committed - (page
|
|
750
|
+
return (page->slice_committed == 0 ? mi_page_size(page) : page->slice_committed - mi_page_slice_offset_of(page,0));
|
|
725
751
|
}
|
|
726
752
|
|
|
727
753
|
// are all blocks in a page freed?
|
|
@@ -746,7 +772,7 @@ static inline bool mi_page_is_expandable(const mi_page_t* page) {
|
|
|
746
772
|
}
|
|
747
773
|
|
|
748
774
|
|
|
749
|
-
static inline bool mi_page_is_full(mi_page_t* page) {
|
|
775
|
+
static inline bool mi_page_is_full(const mi_page_t* page) {
|
|
750
776
|
const bool full = (page->reserved == page->used);
|
|
751
777
|
mi_assert_internal(!full || page->free == NULL);
|
|
752
778
|
return full;
|
|
@@ -798,9 +824,11 @@ static inline mi_page_flags_t mi_page_flags(const mi_page_t* page) {
|
|
|
798
824
|
return (mi_page_xthread_id(page) & MI_PAGE_FLAG_MASK);
|
|
799
825
|
}
|
|
800
826
|
|
|
801
|
-
static inline
|
|
802
|
-
|
|
803
|
-
|
|
827
|
+
static inline bool mi_page_flags_set(mi_page_t* page, bool set, mi_page_flags_t newflag) {
|
|
828
|
+
mi_page_flags_t old;
|
|
829
|
+
if (set) { old = mi_atomic_or_relaxed(&page->xthread_id, newflag); }
|
|
830
|
+
else { old = mi_atomic_and_relaxed(&page->xthread_id, ~newflag); }
|
|
831
|
+
return ((old & newflag) == newflag);
|
|
804
832
|
}
|
|
805
833
|
|
|
806
834
|
static inline bool mi_page_is_in_full(const mi_page_t* page) {
|
|
@@ -808,7 +836,17 @@ static inline bool mi_page_is_in_full(const mi_page_t* page) {
|
|
|
808
836
|
}
|
|
809
837
|
|
|
810
838
|
static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) {
|
|
811
|
-
mi_page_flags_set(page, in_full, MI_PAGE_IN_FULL_QUEUE);
|
|
839
|
+
const bool was_in_full = mi_page_flags_set(page, in_full, MI_PAGE_IN_FULL_QUEUE);
|
|
840
|
+
if (was_in_full != in_full) {
|
|
841
|
+
// optimize: maintain pages_full_size to avoid visiting the full queue (issue #1220)
|
|
842
|
+
mi_theap_t* const theap = page->theap;
|
|
843
|
+
mi_assert_internal(theap!=NULL);
|
|
844
|
+
if (theap != NULL) {
|
|
845
|
+
const size_t size = page->capacity * mi_page_block_size(page);
|
|
846
|
+
if (in_full) { theap->pages_full_size += size; }
|
|
847
|
+
else { mi_assert_internal(size <= theap->pages_full_size); theap->pages_full_size -= size; }
|
|
848
|
+
}
|
|
849
|
+
}
|
|
812
850
|
}
|
|
813
851
|
|
|
814
852
|
static inline bool mi_page_has_interior_pointers(const mi_page_t* page) {
|
|
@@ -844,12 +882,12 @@ static inline bool mi_page_is_abandoned_mapped(const mi_page_t* page) {
|
|
|
844
882
|
|
|
845
883
|
static inline void mi_page_set_abandoned_mapped(mi_page_t* page) {
|
|
846
884
|
mi_assert_internal(mi_page_is_abandoned(page));
|
|
847
|
-
mi_atomic_or_relaxed(&page->xthread_id, MI_THREADID_ABANDONED_MAPPED);
|
|
885
|
+
mi_atomic_or_relaxed(&page->xthread_id, (mi_threadid_t)MI_THREADID_ABANDONED_MAPPED);
|
|
848
886
|
}
|
|
849
887
|
|
|
850
888
|
static inline void mi_page_clear_abandoned_mapped(mi_page_t* page) {
|
|
851
889
|
mi_assert_internal(mi_page_is_abandoned_mapped(page));
|
|
852
|
-
mi_atomic_and_relaxed(&page->xthread_id, MI_PAGE_FLAG_MASK);
|
|
890
|
+
mi_atomic_and_relaxed(&page->xthread_id, (mi_threadid_t)MI_PAGE_FLAG_MASK);
|
|
853
891
|
}
|
|
854
892
|
|
|
855
893
|
|
|
@@ -907,7 +945,7 @@ static inline bool mi_page_is_owned(const mi_page_t* page) {
|
|
|
907
945
|
|
|
908
946
|
// get ownership; returns true if the page was not owned before.
|
|
909
947
|
static inline bool mi_page_claim_ownership(mi_page_t* page) {
|
|
910
|
-
const uintptr_t old = mi_atomic_or_acq_rel(&page->xthread_free, 1);
|
|
948
|
+
const uintptr_t old = mi_atomic_or_acq_rel(&page->xthread_free, (uintptr_t)1);
|
|
911
949
|
return ((old&1)==0);
|
|
912
950
|
}
|
|
913
951
|
|
|
@@ -916,17 +954,23 @@ static inline bool mi_page_claim_ownership(mi_page_t* page) {
|
|
|
916
954
|
Guarded objects
|
|
917
955
|
------------------------------------------------------------------- */
|
|
918
956
|
#if MI_GUARDED
|
|
919
|
-
|
|
920
957
|
// we always align guarded pointers in a block at an offset
|
|
921
958
|
// the block `next` field is then used as a tag to distinguish regular offset aligned blocks from guarded ones
|
|
922
959
|
#define MI_BLOCK_TAG_ALIGNED ((mi_encoded_t)(0))
|
|
923
960
|
#define MI_BLOCK_TAG_GUARDED (~MI_BLOCK_TAG_ALIGNED)
|
|
961
|
+
#endif
|
|
924
962
|
|
|
925
963
|
static inline bool mi_block_ptr_is_guarded(const mi_block_t* block, const void* p) {
|
|
964
|
+
#if MI_GUARDED
|
|
926
965
|
const ptrdiff_t offset = (uint8_t*)p - (uint8_t*)block;
|
|
927
966
|
return (offset >= (ptrdiff_t)(sizeof(mi_block_t)) && block->next == MI_BLOCK_TAG_GUARDED);
|
|
967
|
+
#else
|
|
968
|
+
MI_UNUSED(block); MI_UNUSED(p);
|
|
969
|
+
return false;
|
|
970
|
+
#endif
|
|
928
971
|
}
|
|
929
972
|
|
|
973
|
+
#if MI_GUARDED
|
|
930
974
|
static inline bool mi_theap_malloc_use_guarded(mi_theap_t* theap, size_t size) {
|
|
931
975
|
// this code is written to result in fast assembly as it is on the hot path for allocation
|
|
932
976
|
const size_t count = theap->guarded_sample_count - 1; // if the rate was 0, this will underflow and count for a long time..
|
|
@@ -1006,7 +1050,7 @@ static inline uint32_t mi_ptr_encode_canary(const void* null, const void* p, con
|
|
|
1006
1050
|
static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {
|
|
1007
1051
|
mi_track_mem_defined(block,sizeof(mi_block_t));
|
|
1008
1052
|
mi_block_t* next;
|
|
1009
|
-
#
|
|
1053
|
+
#if MI_ENCODE_FREELIST
|
|
1010
1054
|
next = (mi_block_t*)mi_ptr_decode(null, block->next, keys);
|
|
1011
1055
|
#else
|
|
1012
1056
|
MI_UNUSED(keys); MI_UNUSED(null);
|
|
@@ -1018,7 +1062,7 @@ static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* bl
|
|
|
1018
1062
|
|
|
1019
1063
|
static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) {
|
|
1020
1064
|
mi_track_mem_undefined(block,sizeof(mi_block_t));
|
|
1021
|
-
#
|
|
1065
|
+
#if MI_ENCODE_FREELIST
|
|
1022
1066
|
block->next = mi_ptr_encode(null, next, keys);
|
|
1023
1067
|
#else
|
|
1024
1068
|
MI_UNUSED(keys); MI_UNUSED(null);
|
|
@@ -1028,7 +1072,7 @@ static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const
|
|
|
1028
1072
|
}
|
|
1029
1073
|
|
|
1030
1074
|
static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) {
|
|
1031
|
-
#
|
|
1075
|
+
#if MI_ENCODE_FREELIST
|
|
1032
1076
|
mi_block_t* next = mi_block_nextx(page,block,page->keys);
|
|
1033
1077
|
// check for free list corruption: is `next` at least in the same page?
|
|
1034
1078
|
// TODO: check if `next` is `page->block_size` aligned?
|
|
@@ -1044,7 +1088,7 @@ static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t*
|
|
|
1044
1088
|
}
|
|
1045
1089
|
|
|
1046
1090
|
static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) {
|
|
1047
|
-
#
|
|
1091
|
+
#if MI_ENCODE_FREELIST
|
|
1048
1092
|
mi_block_set_nextx(page,block,next, page->keys);
|
|
1049
1093
|
#else
|
|
1050
1094
|
MI_UNUSED(page);
|
|
@@ -126,6 +126,9 @@ void _mi_prim_thread_associate_default_theap(mi_theap_t* theap);
|
|
|
126
126
|
// Is this thread part of a thread pool?
|
|
127
127
|
bool _mi_prim_thread_is_in_threadpool(void);
|
|
128
128
|
|
|
129
|
+
// Yield to other threads. Should be similar to `sleep(0)`.
|
|
130
|
+
// Is called only in rare situations and does not have to be lightning fast.
|
|
131
|
+
void _mi_prim_thread_yield(void);
|
|
129
132
|
|
|
130
133
|
//-------------------------------------------------------------------
|
|
131
134
|
// Access to TLS (thread local storage) slots.
|
|
@@ -253,14 +256,16 @@ extern mi_decl_hidden bool _mi_process_is_initialized; // has mi_
|
|
|
253
256
|
// but unfortunately, it seems we cannot test for this reliably at this time (see issue #883)
|
|
254
257
|
// Nevertheless, it seems needed on older graviton platforms (see issue #851).
|
|
255
258
|
// For now, we only enable this for specific platforms.
|
|
256
|
-
#if !defined(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
#if !defined(MI_USE_BUILTIN_THREAD_POINTER) /* allow user override */
|
|
260
|
+
#if !defined(__APPLE__) /* on apple (M1) the wrong register is read (tpidr_el0 instead of tpidrro_el0) so fall back to TLS slot assembly (<https://github.com/microsoft/mimalloc/issues/343#issuecomment-763272369>)*/ \
|
|
261
|
+
&& !defined(__CYGWIN__) \
|
|
262
|
+
&& !defined(MI_LIBC_MUSL) \
|
|
263
|
+
&& (!defined(__clang_major__) || __clang_major__ >= 14) /* older clang versions emit bad code; fall back to using the TLS slot (<https://lore.kernel.org/linux-arm-kernel/202110280952.352F66D8@keescook/T/>) */
|
|
264
|
+
#if (defined(__GNUC__) && (__GNUC__ >= 7) && defined(__aarch64__)) /* aarch64 for older gcc versions (issue #851) */ \
|
|
265
|
+
|| (defined(__GNUC__) && (__GNUC__ >= 11) && defined(__x86_64__)) \
|
|
266
|
+
|| (defined(__clang_major__) && (__clang_major__ >= 14) && (defined(__aarch64__) || defined(__x86_64__)))
|
|
267
|
+
#define MI_USE_BUILTIN_THREAD_POINTER 1
|
|
268
|
+
#endif
|
|
264
269
|
#endif
|
|
265
270
|
#endif
|
|
266
271
|
|
|
@@ -276,8 +281,10 @@ static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
|
|
|
276
281
|
// Get a unique id for the current thread.
|
|
277
282
|
#if defined(MI_PRIM_THREAD_ID)
|
|
278
283
|
|
|
279
|
-
static inline mi_threadid_t
|
|
280
|
-
|
|
284
|
+
static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
|
|
285
|
+
const mi_threadid_t tid = MI_PRIM_THREAD_ID(); // used for example by CPython for a free threaded build (see python/cpython#115488)
|
|
286
|
+
mi_assert_internal( (tid & 0x03) == 0 ); // mimalloc reserves the bottom 2 bits
|
|
287
|
+
return tid;
|
|
281
288
|
}
|
|
282
289
|
|
|
283
290
|
#elif defined(_WIN32)
|
|
@@ -363,14 +370,14 @@ static inline mi_theap_t* _mi_theap_cached(void);
|
|
|
363
370
|
|
|
364
371
|
#if defined(_WIN32)
|
|
365
372
|
#define MI_TLS_MODEL_DYNAMIC_WIN32 1
|
|
366
|
-
#elif defined(__APPLE__) // macOS
|
|
373
|
+
#elif defined(__APPLE__) && MI_HAS_TLS_SLOT && !defined(__POWERPC__) // macOS on arm64 or x64
|
|
367
374
|
// #define MI_TLS_MODEL_DYNAMIC_PTHREADS 1 // also works but a bit slower
|
|
368
375
|
#define MI_TLS_MODEL_FIXED_SLOT 1
|
|
369
376
|
#define MI_TLS_MODEL_FIXED_SLOT_DEFAULT 108 // seems unused. @apple: it would be great to get 2 official slots for custom allocators :-)
|
|
370
377
|
#define MI_TLS_MODEL_FIXED_SLOT_CACHED 109
|
|
371
378
|
// we used before __PTK_FRAMEWORK_OLDGC_KEY9 (89) but that seems used now.
|
|
372
379
|
// see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h>
|
|
373
|
-
#elif defined(__OpenBSD__) || defined(__ANDROID__)
|
|
380
|
+
#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__ANDROID__)
|
|
374
381
|
#define MI_TLS_MODEL_DYNAMIC_PTHREADS 1
|
|
375
382
|
// #define MI_TLS_MODEL_DYNAMIC_PTHREADS_DEFAULT_ENTRY_IS_NULL 1
|
|
376
383
|
#else
|
|
@@ -497,11 +504,11 @@ static inline bool _mi_thread_is_initialized(void) {
|
|
|
497
504
|
// Get (and possible create) the theap belonging to a heap
|
|
498
505
|
// We cache the last accessed theap in `_mi_theap_cached` for better performance.
|
|
499
506
|
static inline mi_theap_t* _mi_heap_theap(const mi_heap_t* heap) {
|
|
500
|
-
mi_theap_t* theap = _mi_theap_cached();
|
|
507
|
+
mi_theap_t* theap = _mi_theap_cached();
|
|
501
508
|
#if MI_THEAP_INITASNULL
|
|
502
|
-
if mi_likely(theap!=NULL && theap
|
|
509
|
+
if mi_likely(theap!=NULL && _mi_theap_heap(theap)==heap) return theap;
|
|
503
510
|
#else
|
|
504
|
-
if mi_likely(theap
|
|
511
|
+
if mi_likely(_mi_theap_heap(theap)==heap) return theap;
|
|
505
512
|
#endif
|
|
506
513
|
return _mi_heap_theap_get_or_init(heap);
|
|
507
514
|
}
|
|
@@ -510,14 +517,14 @@ static inline mi_theap_t* _mi_heap_theap(const mi_heap_t* heap) {
|
|
|
510
517
|
static inline mi_theap_t* _mi_heap_theap_peek(const mi_heap_t* heap) {
|
|
511
518
|
mi_theap_t* theap = _mi_theap_cached();
|
|
512
519
|
#if MI_THEAP_INITASNULL
|
|
513
|
-
if mi_unlikely(theap==NULL || theap
|
|
520
|
+
if mi_unlikely(theap==NULL || _mi_theap_heap(theap)!=heap)
|
|
514
521
|
#else
|
|
515
|
-
if mi_unlikely(theap
|
|
522
|
+
if mi_unlikely(_mi_theap_heap(theap)!=heap)
|
|
516
523
|
#endif
|
|
517
524
|
{
|
|
518
525
|
theap = _mi_heap_theap_get_peek(heap); // don't update the cache on a query (?)
|
|
519
526
|
}
|
|
520
|
-
mi_assert(theap==NULL || theap
|
|
527
|
+
mi_assert(theap==NULL || _mi_theap_heap(theap)==heap);
|
|
521
528
|
return theap;
|
|
522
529
|
}
|
|
523
530
|
|
|
@@ -84,7 +84,8 @@ defined, undefined, or not accessible at all:
|
|
|
84
84
|
|
|
85
85
|
#include "../src/prim/windows/etw.h"
|
|
86
86
|
|
|
87
|
-
#define mi_track_init() EventRegistermicrosoft_windows_mimalloc()
|
|
87
|
+
#define mi_track_init() EventRegistermicrosoft_windows_mimalloc()
|
|
88
|
+
#define mi_track_done() EventUnregistermicrosoft_windows_mimalloc()
|
|
88
89
|
#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size)
|
|
89
90
|
#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)(p), size)
|
|
90
91
|
|
|
@@ -104,7 +105,7 @@ defined, undefined, or not accessible at all:
|
|
|
104
105
|
// Utility definitions
|
|
105
106
|
|
|
106
107
|
#ifndef mi_track_resize
|
|
107
|
-
#define mi_track_resize(p,oldsize,newsize) mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false)
|
|
108
|
+
#define mi_track_resize(p,oldsize,newsize) do{ mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false); } while(0)
|
|
108
109
|
#endif
|
|
109
110
|
|
|
110
111
|
#ifndef mi_track_align
|
|
@@ -115,6 +116,10 @@ defined, undefined, or not accessible at all:
|
|
|
115
116
|
#define mi_track_init()
|
|
116
117
|
#endif
|
|
117
118
|
|
|
119
|
+
#ifndef mi_track_done
|
|
120
|
+
#define mi_track_done()
|
|
121
|
+
#endif
|
|
122
|
+
|
|
118
123
|
#ifndef mi_track_mem_defined
|
|
119
124
|
#define mi_track_mem_defined(p,size)
|
|
120
125
|
#endif
|
|
@@ -54,17 +54,12 @@ terms of the MIT license. A copy of the license can be found in the file
|
|
|
54
54
|
// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).
|
|
55
55
|
// #define MI_STAT 1
|
|
56
56
|
|
|
57
|
-
// Define MI_SECURE to enable security mitigations
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
// #define MI_SECURE 2 // guard page around each mimalloc page (can fragment VMA's with large theaps..)
|
|
64
|
-
//
|
|
65
|
-
// The next two levels can have more performance cost:
|
|
66
|
-
// #define MI_SECURE 3 // randomize allocations, encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)
|
|
67
|
-
// #define MI_SECURE 4 // checks for double free. (may be more expensive)
|
|
57
|
+
// Define MI_SECURE to enable security mitigations
|
|
58
|
+
// #define MI_SECURE 1 // guard pages around meta data, randomize arena allocation addresses (like ASLR), abort on detected meta data corruption
|
|
59
|
+
// #define MI_SECURE 2 // randomize relative allocation addresses (within mimalloc pages)
|
|
60
|
+
// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)
|
|
61
|
+
// #define MI_SECURE 4 // checks for double free (may be more expensive) (`-DMI_SECURE=ON`)
|
|
62
|
+
// #define MI_SECURE 5 // guard page at the end of each mimalloc page (expensive!) (`-DMI_SECURE_FULL=ON`)
|
|
68
63
|
|
|
69
64
|
#if !defined(MI_SECURE)
|
|
70
65
|
#define MI_SECURE 0
|
|
@@ -91,11 +86,9 @@ terms of the MIT license. A copy of the license can be found in the file
|
|
|
91
86
|
#endif
|
|
92
87
|
#endif
|
|
93
88
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
#if MI_GUARDED
|
|
98
|
-
#define MI_PADDING 0
|
|
89
|
+
// Enable guard pages behind objects of a certain size (set by the MIMALLOC_GUARDED_MIN/MAX/SAMPLE_RATE options)
|
|
90
|
+
#if !defined(MI_GUARDED) && MI_DEBUG && !defined(NDEBUG) && !MI_PAGE_META_ALIGNED_FREE_SMALL
|
|
91
|
+
#define MI_GUARDED 1
|
|
99
92
|
#endif
|
|
100
93
|
|
|
101
94
|
// Reserve extra padding at the end of each block to be more resilient against theap block overflows.
|
|
@@ -123,6 +116,40 @@ terms of the MIT license. A copy of the license can be found in the file
|
|
|
123
116
|
#define MI_ENABLE_LARGE_PAGES 1
|
|
124
117
|
#endif
|
|
125
118
|
|
|
119
|
+
// Place page meta info at the start of the page area or keep it separate?
|
|
120
|
+
// Separate keeps the page info at the arena start (default) which is more secure
|
|
121
|
+
// and reduces wasted space due to alignment and block sizes.
|
|
122
|
+
// (but also reserves more memory up front (about 2MiB per GiB))
|
|
123
|
+
#if !defined(MI_PAGE_META_IS_SEPARATED)
|
|
124
|
+
#if MI_PAGE_MAP_FLAT
|
|
125
|
+
#define MI_PAGE_META_IS_SEPARATED 0
|
|
126
|
+
#else
|
|
127
|
+
#define MI_PAGE_META_IS_SEPARATED 1
|
|
128
|
+
#endif
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
// We can choose to only put page info of small pages at the start of the page area.
|
|
132
|
+
// This can be used to have a slightly faster `mi_free_small` function for specialized
|
|
133
|
+
// cases (like language runtime systems).
|
|
134
|
+
#if !defined(MI_PAGE_META_ALIGNED_FREE_SMALL)
|
|
135
|
+
#define MI_PAGE_META_ALIGNED_FREE_SMALL 0
|
|
136
|
+
#endif
|
|
137
|
+
|
|
138
|
+
// Configuration checks
|
|
139
|
+
#if !MI_PAGE_META_IS_SEPARATED && MI_SECURE
|
|
140
|
+
#error "secure mode should use separated page infos"
|
|
141
|
+
#endif
|
|
142
|
+
#if MI_PAGE_META_ALIGNED_FREE_SMALL && MI_SECURE
|
|
143
|
+
#error "secure mode cannot use MI_PAGE_META_ALIGNED_FREE_SMALL"
|
|
144
|
+
#endif
|
|
145
|
+
#if MI_PAGE_META_IS_SEPARATED && MI_PAGE_MAP_FLAT
|
|
146
|
+
#error "cannot have a flat page map with separated page infos"
|
|
147
|
+
#endif
|
|
148
|
+
#if MI_DEBUG && NDEBUG
|
|
149
|
+
#warning "mimalloc assertions enabled in a release build"
|
|
150
|
+
#endif
|
|
151
|
+
|
|
152
|
+
|
|
126
153
|
// --------------------------------------------------------------
|
|
127
154
|
// Sizes of internal data-structures
|
|
128
155
|
// (comments specify sizes on 64-bit, usually 32-bit is halved)
|
|
@@ -132,7 +159,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
|
|
132
159
|
#ifndef MI_ARENA_SLICE_SHIFT
|
|
133
160
|
#ifdef MI_SMALL_PAGE_SHIFT // backward compatibility
|
|
134
161
|
#define MI_ARENA_SLICE_SHIFT MI_SMALL_PAGE_SHIFT
|
|
135
|
-
#elif MI_SECURE && __APPLE__ && MI_ARCH_ARM64
|
|
162
|
+
#elif MI_SECURE>=5 && __APPLE__ && MI_ARCH_ARM64
|
|
136
163
|
#define MI_ARENA_SLICE_SHIFT (17) // 128 KiB to not waste too much due to 16 KiB guard pages
|
|
137
164
|
#else
|
|
138
165
|
#define MI_ARENA_SLICE_SHIFT (13 + MI_SIZE_SHIFT) // 64 KiB (32 KiB on 32-bit)
|
|
@@ -313,7 +340,7 @@ typedef size_t mi_page_flags_t;
|
|
|
313
340
|
// There are two special threadid's: 0 for pages that are abandoned (and not in a theap queue),
|
|
314
341
|
// and 4 for abandoned & mapped threads -- abandoned-mapped pages are abandoned but also mapped
|
|
315
342
|
// in an arena (in `mi_heap_t.arena_pages.pages_abandoned`) so these can be quickly found for reuse.
|
|
316
|
-
//
|
|
343
|
+
// Abandoning partially used pages allows for sharing of this memory between threads (in particular if threads are blocked)
|
|
317
344
|
#define MI_THREADID_ABANDONED MI_ZU(0)
|
|
318
345
|
#define MI_THREADID_ABANDONED_MAPPED (MI_PAGE_FLAG_MASK + 1)
|
|
319
346
|
|
|
@@ -392,12 +419,6 @@ typedef struct mi_page_s {
|
|
|
392
419
|
#define MI_PAGE_OSPAGE_BLOCK_ALIGN2 (4*MI_KiB) // also aligns any multiple of this size to avoid TLB misses.
|
|
393
420
|
#define MI_PAGE_MAX_OVERALLOC_ALIGN MI_ARENA_SLICE_SIZE // (64 KiB) limit for which we overallocate in arena pages, beyond this use OS allocation
|
|
394
421
|
|
|
395
|
-
#if (MI_ENCODE_FREELIST || MI_PADDING) && MI_SIZE_SIZE == 8
|
|
396
|
-
#define MI_PAGE_INFO_SIZE ((MI_INTPTR_SHIFT+2)*32) // 160 >= sizeof(mi_page_t)
|
|
397
|
-
#else
|
|
398
|
-
#define MI_PAGE_INFO_SIZE ((MI_INTPTR_SHIFT+1)*32) // 128/96 >= sizeof(mi_page_t)
|
|
399
|
-
#endif
|
|
400
|
-
|
|
401
422
|
// The max object sizes are intended to not waste more than ~ 12.5% internally over the page sizes.
|
|
402
423
|
#define MI_SMALL_MAX_OBJ_SIZE ((MI_SMALL_PAGE_SIZE-MI_PAGE_OSPAGE_BLOCK_ALIGN2)/6) // = 10 KiB
|
|
403
424
|
#if MI_ENABLE_LARGE_PAGES
|
|
@@ -423,7 +444,7 @@ typedef enum mi_page_kind_e {
|
|
|
423
444
|
MI_PAGE_MEDIUM, // medium blocks go into 512KiB pages
|
|
424
445
|
MI_PAGE_LARGE, // larger blocks go into 4MiB pages (if `MI_ENABLE_LARGE_PAGES==1`)
|
|
425
446
|
MI_PAGE_SINGLETON // page containing a single block.
|
|
426
|
-
// used for blocks `> MI_LARGE_MAX_OBJ_SIZE` or an
|
|
447
|
+
// used for blocks `> MI_LARGE_MAX_OBJ_SIZE` or an alignment `> MI_PAGE_MAX_OVERALLOC_ALIGN`.
|
|
427
448
|
} mi_page_kind_t;
|
|
428
449
|
|
|
429
450
|
|
|
@@ -482,21 +503,23 @@ typedef struct mi_padding_s {
|
|
|
482
503
|
// A thread-local heap ("theap") owns a set of thread-local pages.
|
|
483
504
|
struct mi_theap_s {
|
|
484
505
|
mi_tld_t* tld; // thread-local data
|
|
485
|
-
mi_heap_t*
|
|
506
|
+
_Atomic(mi_heap_t*) heap; // the heap this theap belongs to.
|
|
507
|
+
_Atomic(size_t) refcount; // reference count
|
|
486
508
|
unsigned long long heartbeat; // monotonic heartbeat count
|
|
487
509
|
uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`)
|
|
488
510
|
mi_random_ctx_t random; // random number context used for secure allocation
|
|
489
511
|
size_t page_count; // total number of pages in the `pages` queues.
|
|
490
512
|
size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues)
|
|
491
513
|
size_t page_retired_max; // largest retired index into the `pages` array.
|
|
514
|
+
size_t pages_full_size; // optimization: total size of blocks in the pages of the full queue (issue #1220)
|
|
492
515
|
long generic_count; // how often is `_mi_malloc_generic` called?
|
|
493
516
|
long generic_collect_count; // how often is `_mi_malloc_generic` called without collecting?
|
|
494
517
|
|
|
495
518
|
mi_theap_t* tnext; // list of theaps in this thread
|
|
496
|
-
mi_theap_t* tprev;
|
|
519
|
+
mi_theap_t* tprev;
|
|
497
520
|
mi_theap_t* hnext; // list of theaps of the owning `heap`
|
|
498
521
|
mi_theap_t* hprev;
|
|
499
|
-
|
|
522
|
+
|
|
500
523
|
long page_full_retain; // how many full pages can be retained per queue (before abandoning them)
|
|
501
524
|
bool allow_page_reclaim; // `true` if this theap should not reclaim abandoned pages
|
|
502
525
|
bool allow_page_abandon; // `true` if this theap can abandon pages to reduce memory footprint
|
|
@@ -604,6 +627,7 @@ struct mi_tld_s {
|
|
|
604
627
|
int numa_node; // thread preferred numa node
|
|
605
628
|
mi_subproc_t* subproc; // sub-process this thread belongs to.
|
|
606
629
|
mi_theap_t* theaps; // list of theaps in this thread (so we can abandon all when the thread terminates)
|
|
630
|
+
mi_lock_t theaps_lock; // lock as the theaps list is sometimes accessed from another thread (on `mi_heap_free`)
|
|
607
631
|
bool recurse; // true if deferred was called; used to prevent infinite recursion.
|
|
608
632
|
bool is_in_threadpool; // true if this thread is part of a threadpool (and can run arbitrary tasks)
|
|
609
633
|
mi_memid_t memid; // provenance of the tld memory itself (meta or OS)
|
|
@@ -632,7 +656,7 @@ typedef struct mi_bbitmap_s mi_bbitmap_t; // atomic binned bitmap (defined in
|
|
|
632
656
|
typedef struct mi_arena_pages_s {
|
|
633
657
|
mi_bitmap_t* pages; // all registered pages (abandoned and owned)
|
|
634
658
|
mi_bitmap_t* pages_abandoned[MI_ARENA_BIN_COUNT]; // abandoned pages per size bin (a set bit means the start of the page)
|
|
635
|
-
// followed by the bitmaps (whose
|
|
659
|
+
// followed by the bitmaps (whose siz`es depend on the arena size)
|
|
636
660
|
} mi_arena_pages_t;
|
|
637
661
|
|
|
638
662
|
|
|
@@ -651,10 +675,14 @@ typedef struct mi_arena_s {
|
|
|
651
675
|
mi_commit_fun_t* commit_fun; // custom commit/decommit memory
|
|
652
676
|
void* commit_fun_arg; // user argument for a custom commit function
|
|
653
677
|
|
|
678
|
+
size_t total_size; // for (user given) memory more than MI_ARENA_MAX_SIZE, we use N arena's to cover it. The first (parent) has the total size (and the other sub-arena's 0).
|
|
679
|
+
mi_arena_t* parent; // if this is a sub arena, this points to the first one in the memory area.
|
|
680
|
+
|
|
654
681
|
mi_bbitmap_t* slices_free; // is the slice free? (a binned bitmap with size classes)
|
|
655
682
|
mi_bitmap_t* slices_committed; // is the slice committed? (i.e. accessible)
|
|
656
683
|
mi_bitmap_t* slices_dirty; // is the slice potentially non-zero?
|
|
657
684
|
mi_bitmap_t* slices_purge; // slices that can be purged
|
|
685
|
+
mi_page_t* pages_meta; // pre-allocated `slice_count` page meta info -- only used if `MI_PAGE_META_IS_SEPARATED!=0`
|
|
658
686
|
mi_arena_pages_t pages_main; // arena page bitmaps for the main heap are allocated up front as well
|
|
659
687
|
|
|
660
688
|
// followed by the bitmaps (whose sizes depend on the arena size)
|
|
@@ -19,7 +19,7 @@ not accidentally mix pointers from different allocators).
|
|
|
19
19
|
|
|
20
20
|
// Standard C allocation
|
|
21
21
|
#define malloc(n) mi_malloc(n)
|
|
22
|
-
#define calloc(n
|
|
22
|
+
#define calloc(c,n) mi_calloc(c,n)
|
|
23
23
|
#define realloc(p,n) mi_realloc(p,n)
|
|
24
24
|
#define free(p) mi_free(p)
|
|
25
25
|
|
|
@@ -30,26 +30,26 @@ not accidentally mix pointers from different allocators).
|
|
|
30
30
|
// Microsoft extensions
|
|
31
31
|
#define _expand(p,n) mi_expand(p,n)
|
|
32
32
|
#define _msize(p) mi_usable_size(p)
|
|
33
|
-
#define _recalloc(p,n
|
|
33
|
+
#define _recalloc(p,c,n) mi_recalloc(p,c,n)
|
|
34
34
|
|
|
35
35
|
#define _strdup(s) mi_strdup(s)
|
|
36
36
|
#define _strndup(s,n) mi_strndup(s,n)
|
|
37
|
-
#define _wcsdup(s)
|
|
37
|
+
#define _wcsdup(s) mi_wcsdup(s)
|
|
38
38
|
#define _mbsdup(s) mi_mbsdup(s)
|
|
39
|
-
#define _dupenv_s(
|
|
40
|
-
#define _wdupenv_s(
|
|
39
|
+
#define _dupenv_s(buf,n,nm) mi_dupenv_s(buf,n,nm)
|
|
40
|
+
#define _wdupenv_s(buf,n,nm) mi_wdupenv_s(buf,n,nm)
|
|
41
41
|
|
|
42
42
|
// Various Posix and Unix variants
|
|
43
43
|
#define reallocf(p,n) mi_reallocf(p,n)
|
|
44
44
|
#define malloc_size(p) mi_usable_size(p)
|
|
45
45
|
#define malloc_usable_size(p) mi_usable_size(p)
|
|
46
|
-
#define malloc_good_size(
|
|
46
|
+
#define malloc_good_size(n) mi_malloc_good_size(n)
|
|
47
47
|
#define cfree(p) mi_free(p)
|
|
48
48
|
|
|
49
49
|
#define valloc(n) mi_valloc(n)
|
|
50
50
|
#define pvalloc(n) mi_pvalloc(n)
|
|
51
|
-
#define reallocarray(p,
|
|
52
|
-
#define reallocarr(
|
|
51
|
+
#define reallocarray(p,c,n) mi_reallocarray(p,c,n)
|
|
52
|
+
#define reallocarr(ptrp,c,n) mi_reallocarr(ptrp,c,n)
|
|
53
53
|
#define memalign(a,n) mi_memalign(a,n)
|
|
54
54
|
#define aligned_alloc(a,n) mi_aligned_alloc(a,n)
|
|
55
55
|
#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n)
|
|
@@ -58,11 +58,11 @@ not accidentally mix pointers from different allocators).
|
|
|
58
58
|
// Microsoft aligned variants
|
|
59
59
|
#define _aligned_malloc(n,a) mi_malloc_aligned(n,a)
|
|
60
60
|
#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a)
|
|
61
|
-
#define _aligned_recalloc(p,
|
|
61
|
+
#define _aligned_recalloc(p,c,n,a) mi_aligned_recalloc(p,c,n,a)
|
|
62
62
|
#define _aligned_msize(p,a,o) mi_usable_size(p)
|
|
63
63
|
#define _aligned_free(p) mi_free(p)
|
|
64
64
|
#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o)
|
|
65
65
|
#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o)
|
|
66
|
-
#define _aligned_offset_recalloc(p,
|
|
66
|
+
#define _aligned_offset_recalloc(p,c,n,a,o) mi_recalloc_aligned_at(p,c,n,a,o)
|
|
67
67
|
|
|
68
68
|
#endif // MIMALLOC_OVERRIDE_H
|