From 4bf63300b3935245559833887277e4aa06814940 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Mon, 20 Mar 2023 12:29:36 -0700 Subject: [PATCH] fix alignment issue #700 --- ide/vs2022/mimalloc.vcxproj | 2 +- src/segment.c | 4 +++- test/main-override-static.c | 9 +++++++++ test/test-api.c | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ide/vs2022/mimalloc.vcxproj b/ide/vs2022/mimalloc.vcxproj index 07a854ab..894c5030 100644 --- a/ide/vs2022/mimalloc.vcxproj +++ b/ide/vs2022/mimalloc.vcxproj @@ -116,7 +116,7 @@ true Default ../../include - MI_DEBUG=4;MI_SECURE=0;%(PreprocessorDefinitions); + MI_DEBUG=0;MI_SECURE=0;%(PreprocessorDefinitions); CompileAsCpp false stdcpp20 diff --git a/src/segment.c b/src/segment.c index 1b73b19a..1e23bb1a 100644 --- a/src/segment.c +++ b/src/segment.c @@ -316,7 +316,9 @@ static uint8_t* _mi_segment_page_start_from_slice(const mi_segment_t* segment, c ptrdiff_t idx = slice - segment->slices; size_t psize = (size_t)slice->slice_count * MI_SEGMENT_SLICE_SIZE; // make the start not OS page aligned for smaller blocks to avoid page/cache effects - size_t start_offset = (xblock_size >= MI_INTPTR_SIZE && xblock_size <= 1024 ? 3*MI_MAX_ALIGN_GUARANTEE : 0); + // note: the offset must always be an xblock_size multiple since we assume small allocations + // are aligned (see `mi_heap_malloc_aligned`). + size_t start_offset = (xblock_size >= MI_INTPTR_SIZE && xblock_size <= 512 ? xblock_size : 0); if (page_size != NULL) { *page_size = psize - start_offset; } return (uint8_t*)segment + ((idx*MI_SEGMENT_SLICE_SIZE) + start_offset); } diff --git a/test/main-override-static.c b/test/main-override-static.c index 534c8849..5e8b7333 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -20,6 +20,7 @@ static void negative_stat(void); static void alloc_huge(void); static void test_heap_walk(void); static void test_heap_arena(void); +static void test_align(void); int main() { mi_version(); @@ -37,6 +38,7 @@ int main() { // alloc_huge(); // test_heap_walk(); // test_heap_arena(); + test_align(); void* p1 = malloc(78); void* p2 = malloc(24); @@ -68,6 +70,13 @@ int main() { return 0; } +static void test_align() { + void* p = mi_malloc_aligned(256, 256); + if (((uintptr_t)p % 256) != 0) { + fprintf(stderr, "%p is not 256 alignend!\n", p); + } +} + static void invalid_free() { free((void*)0xBADBEEF); realloc((void*)0xBADBEEF,10); diff --git a/test/test-api.c b/test/test-api.c index c78e1972..1967dad7 100644 --- a/test/test-api.c +++ b/test/test-api.c @@ -212,6 +212,24 @@ int main(void) { result = mi_heap_contains_block(heap, p); mi_heap_destroy(heap); } + CHECK_BODY("malloc-aligned12") { + bool ok = true; + const size_t align = 256; + for (int j = 1; j < 1000; j++) { + void* ps[1000]; + for (int i = 0; i < 1000 && ok; i++) { + ps[i] = mi_malloc_aligned(j // size + , align); + if (ps[i] == NULL || ((uintptr_t)(ps[i]) % align) != 0) { + ok = false; + } + } + for (int i = 0; i < 1000 && ok; i++) { + mi_free(ps[i]); + } + } + result = ok; + }; CHECK_BODY("malloc-aligned-at1") { void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p); };