From 8abf5e29c693c65ad104dbb60501ff082c72025b Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Sun, 15 Mar 2026 20:57:24 +0100 Subject: [PATCH 1/2] Fix cmpctmalloc crash for large aligned allocations. The aligned alloc path didn't check size before entering the bucket allocator. On ESP32-P4, cache alignment requirements (64 bytes) put large allocations (e.g. 32KB DMA pool) into the bucket path instead of page_alloc, causing a fatal in size_to_index_helper. --- components/heap/third_party/dartino/cmpctmalloc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/heap/third_party/dartino/cmpctmalloc.c b/components/heap/third_party/dartino/cmpctmalloc.c index 132c9015cc64..ff5ac4ff2c20 100644 --- a/components/heap/third_party/dartino/cmpctmalloc.c +++ b/components/heap/third_party/dartino/cmpctmalloc.c @@ -1366,6 +1366,17 @@ IRAM_ATTR void *cmpct_aligned_alloc_impl(cmpct_heap_t *heap, size_t size, size_t if (alignment <= NATURAL_ALIGNMENT) return cmpct_malloc_impl(heap, size); + // If the size is too large for the bucket allocator, use page_alloc + // directly. Without this check, size_to_index_allocating will fatal + // for sizes above SMALL_ALLOCATION_LIMIT. + if (size >= SMALL_ALLOCATION_LIMIT) { + lock(heap); + void *tag = GET_THREAD_LOCAL_TAG; + void *result = page_alloc(heap, PAGES_FOR_BYTES(size), alignment, tag, /* for_malloc = */ false); + unlock(heap); + return result; + } + size = ROUND_UP(size, NATURAL_ALIGNMENT); // Our approach to aligned allocations requires us to temporarily create a From 566c8c888bb4063329f35471e605c70c82c37ec7 Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Wed, 18 Mar 2026 21:35:22 +0100 Subject: [PATCH 2/2] Feedback. --- components/heap/third_party/dartino/cmpctmalloc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/components/heap/third_party/dartino/cmpctmalloc.c b/components/heap/third_party/dartino/cmpctmalloc.c index ff5ac4ff2c20..1e12f05e5630 100644 --- a/components/heap/third_party/dartino/cmpctmalloc.c +++ b/components/heap/third_party/dartino/cmpctmalloc.c @@ -1353,7 +1353,7 @@ IRAM_ATTR void *cmpct_aligned_alloc_impl(cmpct_heap_t *heap, size_t size, size_t // The page allocator already has the ability to return allocations that // are more aligned than the page size. - if (alignment >= PAGE_SIZE / 2) { + if (alignment >= PAGE_SIZE / 2 || size >= PAGE_SIZE / 4 * 3) { // We take 2k (half-page) allocations in here too, because treating them as // page allocations will waste 2k, but putting them in the normal system // actually wastes even more. @@ -1366,17 +1366,6 @@ IRAM_ATTR void *cmpct_aligned_alloc_impl(cmpct_heap_t *heap, size_t size, size_t if (alignment <= NATURAL_ALIGNMENT) return cmpct_malloc_impl(heap, size); - // If the size is too large for the bucket allocator, use page_alloc - // directly. Without this check, size_to_index_allocating will fatal - // for sizes above SMALL_ALLOCATION_LIMIT. - if (size >= SMALL_ALLOCATION_LIMIT) { - lock(heap); - void *tag = GET_THREAD_LOCAL_TAG; - void *result = page_alloc(heap, PAGES_FOR_BYTES(size), alignment, tag, /* for_malloc = */ false); - unlock(heap); - return result; - } - size = ROUND_UP(size, NATURAL_ALIGNMENT); // Our approach to aligned allocations requires us to temporarily create a