diff --git a/include/mimalloc.h b/include/mimalloc.h index 5e4c3743..39303669 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -256,6 +256,7 @@ typedef struct mi_heap_area_s { size_t committed; // current available bytes for this area size_t used; // number of allocated blocks size_t block_size; // size in bytes of each block + size_t full_block_size; // size in bytes of a full block including padding and metadata. } mi_heap_area_t; typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); diff --git a/src/heap.c b/src/heap.c index 91d2bc42..816d961a 100644 --- a/src/heap.c +++ b/src/heap.c @@ -481,13 +481,14 @@ static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_v if (page->used == 0) return true; const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); // without padding size_t psize; uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize); if (page->capacity == 1) { // optimize page with one block mi_assert_internal(page->used == 1 && page->free == NULL); - return visitor(mi_page_heap(page), area, pstart, bsize, arg); + return visitor(mi_page_heap(page), area, pstart, ubsize, arg); } // create a bitmap of free blocks. @@ -521,7 +522,7 @@ static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_v else if ((m & ((uintptr_t)1 << bit)) == 0) { used_count++; uint8_t* block = pstart + (i * bsize); - if (!visitor(mi_page_heap(page), area, block, bsize, arg)) return false; + if (!visitor(mi_page_heap(page), area, block, ubsize, arg)) return false; } } mi_assert_internal(page->used == used_count); @@ -537,12 +538,14 @@ static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_pa mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun; mi_heap_area_ex_t xarea; const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); xarea.page = page; xarea.area.reserved = page->reserved * bsize; xarea.area.committed = page->capacity * bsize; xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL); xarea.area.used = page->used * bsize; - xarea.area.block_size = bsize; + xarea.area.block_size = ubsize; + xarea.area.full_block_size = bsize; return fun(heap, &xarea, arg); } diff --git a/test/main-override-static.c b/test/main-override-static.c index 07116503..63d90bb0 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -18,6 +18,7 @@ static void test_process_info(void); static void test_reserved(void); static void negative_stat(void); static void alloc_huge(void); +static void test_heap_walk(void); int main() { mi_version(); @@ -31,7 +32,8 @@ int main() { // invalid_free(); // test_reserved(); // negative_stat(); - alloc_huge(); + // alloc_huge(); + test_heap_walk(); void* p1 = malloc(78); void* p2 = malloc(24); @@ -51,8 +53,10 @@ int main() { //free(p1); //p2 = malloc(32); //mi_free(p2); - mi_collect(true); - mi_stats_print(NULL); + + //mi_collect(true); + //mi_stats_print(NULL); + // test_process_info(); return 0; } @@ -189,6 +193,19 @@ static void alloc_huge(void) { mi_free(p); } +static bool test_visit(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) { + printf("I'm visiting a block of size %zu, allocated size %zu\n", block_size, mi_usable_size(block)); + return true; +} + +static void test_heap_walk(void) { + mi_heap_t* heap = mi_heap_new(); + //mi_heap_malloc(heap, 2097152); + mi_heap_malloc(heap, 2067152); + mi_heap_malloc(heap, 2097160); + mi_heap_malloc(heap, 24576); + mi_heap_visit_blocks(heap, true, &test_visit, NULL); +} // ---------------------------- // bin size experiments @@ -360,4 +377,4 @@ static void mi_bins(void) { last_bsize = bsize; } } -#endif \ No newline at end of file +#endif