diff --git a/include/mimalloc-types.h b/include/mimalloc-types.h index 703b07af..db5b52cc 100644 --- a/include/mimalloc-types.h +++ b/include/mimalloc-types.h @@ -94,16 +94,16 @@ terms of the MIT license. A copy of the license can be found in the file #define MI_MEDIUM_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/4) // 128kb on 64-bit #define MI_LARGE_SIZE_MAX (MI_LARGE_PAGE_SIZE/4) // 1Mb on 64-bit #define MI_LARGE_WSIZE_MAX (MI_LARGE_SIZE_MAX>>MI_INTPTR_SHIFT) - +#define MI_HUGE_SIZE_MAX (2*MI_INTPTR_SIZE*MI_SEGMENT_SIZE) // (must match MI_REGION_MAX_ALLOC_SIZE in memory.c) // Minimal alignment necessary. On most platforms 16 bytes are needed // due to SSE registers for example. This must be at least `MI_INTPTR_SIZE` #define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t) // Maximum number of size classes. (spaced exponentially in 12.5% increments) -#define MI_BIN_HUGE (70U) +#define MI_BIN_HUGE (73U) -#if (MI_LARGE_WSIZE_MAX > 393216) +#if (MI_LARGE_WSIZE_MAX >= 655360) #error "define more bins" #endif @@ -326,10 +326,13 @@ typedef struct mi_stats_s { mi_stat_count_t commit_calls; mi_stat_count_t threads; mi_stat_count_t huge; + mi_stat_count_t giant; mi_stat_count_t malloc; mi_stat_count_t segments_cache; mi_stat_counter_t page_no_retire; mi_stat_counter_t searches; + mi_stat_counter_t huge_count; + mi_stat_counter_t giant_count; #if MI_STAT>1 mi_stat_count_t normal[MI_BIN_HUGE+1]; #endif diff --git a/src/heap.c b/src/heap.c index 63954b3b..c18902b1 100644 --- a/src/heap.c +++ b/src/heap.c @@ -246,7 +246,12 @@ static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_ // stats if (page->block_size > MI_LARGE_SIZE_MAX) { - mi_heap_stat_decrease(heap,huge,page->block_size); + if (page->block_size > MI_HUGE_SIZE_MAX) { + _mi_stat_decrease(&heap->tld->stats.giant,page->block_size); + } + else { + _mi_stat_decrease(&heap->tld->stats.huge, page->block_size); + } } #if (MI_STAT>1) size_t inuse = page->used - page->thread_freed; diff --git a/src/init.c b/src/init.c index e5049c01..905df96a 100644 --- a/src/init.c +++ b/src/init.c @@ -42,8 +42,8 @@ const mi_page_t _mi_page_empty = { QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \ QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \ QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \ - QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), /* 69 */ \ - QNULL(MI_LARGE_WSIZE_MAX + 1 /* 393216, Huge queue */), \ + QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \ + QNULL(MI_LARGE_WSIZE_MAX + 1 /* 655360, Huge queue */), \ QNULL(MI_LARGE_WSIZE_MAX + 2) /* Full queue */ } #define MI_STAT_COUNT_NULL() {0,0,0,0} @@ -63,9 +63,8 @@ const mi_page_t _mi_page_empty = { MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ - MI_STAT_COUNT_NULL(), \ - { 0, 0 }, \ - { 0, 0 } \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \ MI_STAT_COUNT_END_NULL() // -------------------------------------------------------- diff --git a/src/page.c b/src/page.c index a8041128..7ac7535e 100644 --- a/src/page.c +++ b/src/page.c @@ -353,7 +353,12 @@ void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { // account for huge pages here if (page->block_size > MI_LARGE_SIZE_MAX) { - _mi_stat_decrease(&page->heap->tld->stats.huge, page->block_size); + if (page->block_size > MI_HUGE_SIZE_MAX) { + _mi_stat_decrease(&page->heap->tld->stats.giant, page->block_size); + } + else { + _mi_stat_decrease(&page->heap->tld->stats.huge, page->block_size); + } } // remove from the page list @@ -702,7 +707,14 @@ static mi_page_t* mi_huge_page_alloc(mi_heap_t* heap, size_t size) { if (page != NULL) { mi_assert_internal(mi_page_immediate_available(page)); mi_assert_internal(page->block_size == block_size); - _mi_stat_increase( &heap->tld->stats.huge, block_size); + if (page->block_size > MI_HUGE_SIZE_MAX) { + _mi_stat_increase(&heap->tld->stats.giant, block_size); + _mi_stat_counter_increase(&heap->tld->stats.giant_count, 1); + } + else { + _mi_stat_increase(&heap->tld->stats.huge, block_size); + _mi_stat_counter_increase(&heap->tld->stats.huge_count, 1); + } } return page; } diff --git a/src/stats.c b/src/stats.c index 8725e48c..e7d398b2 100644 --- a/src/stats.c +++ b/src/stats.c @@ -106,8 +106,11 @@ static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) { mi_stat_add(&stats->malloc, &src->malloc, 1); mi_stat_add(&stats->segments_cache, &src->segments_cache, 1); mi_stat_add(&stats->huge, &src->huge, 1); + mi_stat_add(&stats->giant, &src->giant, 1); mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1); mi_stat_counter_add(&stats->searches, &src->searches, 1); + mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1); + mi_stat_counter_add(&stats->giant_count, &src->giant_count, 1); #if MI_STAT>1 for (size_t i = 0; i <= MI_BIN_HUGE; i++) { if (src->normal[i].allocated > 0 || src->normal[i].freed > 0) { @@ -152,20 +155,29 @@ static void mi_print_count(int64_t n, int64_t unit, FILE* out) { } static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, FILE* out ) { - _mi_fprintf(out,"%10s:", msg); - mi_print_amount(stat->peak, unit, out); - if (unit!=0) { + _mi_fprintf(out,"%10s:", msg); + if (unit>0) { + mi_print_amount(stat->peak, unit, out); mi_print_amount(stat->allocated, unit, out); mi_print_amount(stat->freed, unit, out); - } - if (unit>0) { - mi_print_amount(unit, (unit==0 ? 0 : 1), out); + mi_print_amount(unit, 1, out); mi_print_count(stat->allocated, unit, out); if (stat->allocated > stat->freed) _mi_fprintf(out, " not all freed!\n"); else _mi_fprintf(out, " ok\n"); } + else if (unit<0) { + mi_print_amount(stat->peak, 1, out); + mi_print_amount(stat->allocated, 1, out); + mi_print_amount(stat->freed, 1, out); + mi_print_amount(-unit, 1, out); + mi_print_count((stat->allocated / -unit), 0, out); + if (stat->allocated > stat->freed) + _mi_fprintf(out, " not all freed!\n"); + else + _mi_fprintf(out, " ok\n"); + } else { _mi_fprintf(out, "\n"); } @@ -219,10 +231,12 @@ static void _mi_stats_print(mi_stats_t* stats, double secs, FILE* out) mi_attr_n mi_stat_count_t normal = { 0,0,0,0 }; mi_stats_print_bins(&normal, stats->normal, MI_BIN_HUGE, "normal",out); mi_stat_print(&normal, "normal", 1, out); - mi_stat_print(&stats->huge, "huge", 1, out); + mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out); + mi_stat_print(&stats->giant, "giant", (stats->giant_count.count == 0 ? 1 : -(stats->giant.allocated / stats->giant_count.count)), out); mi_stat_count_t total = { 0,0,0,0 }; mi_stat_add(&total, &normal, 1); mi_stat_add(&total, &stats->huge, 1); + mi_stat_add(&total, &stats->giant, 1); mi_stat_print(&total, "total", 1, out); _mi_fprintf(out, "malloc requested: "); mi_print_amount(stats->malloc.allocated, 1, out); diff --git a/test/main-override-static.c b/test/main-override-static.c index 94891cc3..6ddf4f37 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -6,7 +6,6 @@ #include #include // redefines malloc etc. - int main() { mi_version(); void* p1 = malloc(78);