From d5e39b76c20292a7affd1ed315709578fe1dc7bc Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 4 Dec 2024 10:49:09 +0100 Subject: [PATCH 1/5] [emmalloc] Fix verbose output `toString()` is undeclared. Fixes a regression introduced in commit 04a0cad. --- system/lib/emmalloc.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/system/lib/emmalloc.c b/system/lib/emmalloc.c index 940335c37cf5e..0451f6f7a5ce8 100644 --- a/system/lib/emmalloc.c +++ b/system/lib/emmalloc.c @@ -358,16 +358,16 @@ static void dump_memory_regions() { Region *r = (Region*)root; assert(debug_region_is_consistent(r)); uint8_t *lastRegionEnd = root->endPtr; - MAIN_THREAD_ASYNC_EM_ASM(out('Region block '+ptrToString($0)+' - '+ptrToString($1)+ ' ('+toString(Number($2))+' bytes):'), + MAIN_THREAD_ASYNC_EM_ASM(out('Region block '+ptrToString($0)+' - '+ptrToString($1)+ ' ('+Number($2)+' bytes):'), r, lastRegionEnd, lastRegionEnd-(uint8_t*)r); while ((uint8_t*)r < lastRegionEnd) { - MAIN_THREAD_ASYNC_EM_ASM(out('Region '+ptrToString($0)+', size: '+toString(Number($1))+' ('+($2?"used":"--FREE--")+')'), + MAIN_THREAD_ASYNC_EM_ASM(out('Region '+ptrToString($0)+', size: '+Number($1)+' ('+($2?"used":"--FREE--")+')'), r, r->size, region_ceiling_size(r) == r->size); assert(debug_region_is_consistent(r)); size_t sizeFromCeiling = size_of_region_from_ceiling(r); if (sizeFromCeiling != r->size) { - MAIN_THREAD_ASYNC_EM_ASM(out('Corrupt region! Size marker at the end of the region does not match: '+toString(Number($0))), sizeFromCeiling); + MAIN_THREAD_ASYNC_EM_ASM(out('Corrupt region! Size marker at the end of the region does not match: '+Number($0)), sizeFromCeiling); } if (r->size == 0) { break; @@ -382,7 +382,7 @@ static void dump_memory_regions() { Region *prev = &freeRegionBuckets[i]; Region *fr = freeRegionBuckets[i].next; while (fr != &freeRegionBuckets[i]) { - MAIN_THREAD_ASYNC_EM_ASM(out('In bucket '+$0+', free region '+ptrToString($1)+', size: ' + toString(Number($2)) + ' (size at ceiling: '+toString(Number($3))+'), prev: ' + ptrToString($4) + ', next: ' + ptrToString($5)), + MAIN_THREAD_ASYNC_EM_ASM(out('In bucket '+$0+', free region '+ptrToString($1)+', size: ' + Number($2) + ' (size at ceiling: '+Number($3)+'), prev: ' + ptrToString($4) + ', next: ' + ptrToString($5)), i, fr, fr->size, size_of_region_from_ceiling(fr), fr->prev, fr->next); assert(debug_region_is_consistent(fr)); assert(region_is_free(fr)); @@ -393,7 +393,7 @@ static void dump_memory_regions() { fr = fr->next; } } - MAIN_THREAD_ASYNC_EM_ASM(out('Free bucket index map: ' + toString(Number($0)).toString(2) + ' ' + toString(Number($1)).toString(2)), (uint32_t)(freeRegionBucketsUsed >> 32), (uint32_t)freeRegionBucketsUsed); + MAIN_THREAD_ASYNC_EM_ASM(out('Free bucket index map: ' + Number($0).toString(2) + ' ' + Number($1).toString(2)), (uint32_t)(freeRegionBucketsUsed >> 32), (uint32_t)freeRegionBucketsUsed); MAIN_THREAD_ASYNC_EM_ASM(out("")); } @@ -409,14 +409,14 @@ static int validate_memory_regions() { while (root) { Region *r = (Region*)root; if (!debug_region_is_consistent(r)) { - MAIN_THREAD_ASYNC_EM_ASM(err('Used region '+ptrToString($0)+', size: '+toString(Number($1))+' ('+($2?"used":"--FREE--")+') is corrupt (size markers in the beginning and at the end of the region do not match!)'), + MAIN_THREAD_ASYNC_EM_ASM(err('Used region '+ptrToString($0)+', size: '+Number($1)+' ('+($2?"used":"--FREE--")+') is corrupt (size markers in the beginning and at the end of the region do not match!)'), r, r->size, region_ceiling_size(r) == r->size); return 1; } uint8_t *lastRegionEnd = root->endPtr; while ((uint8_t*)r < lastRegionEnd) { if (!debug_region_is_consistent(r)) { - MAIN_THREAD_ASYNC_EM_ASM(err('Used region '+ptrToString($0)+', size: '+toString(Number($1))+' ('+($2?"used":"--FREE--")+') is corrupt (size markers in the beginning and at the end of the region do not match!)'), + MAIN_THREAD_ASYNC_EM_ASM(err('Used region '+ptrToString($0)+', size: '+Number($1)+' ('+($2?"used":"--FREE--")+') is corrupt (size markers in the beginning and at the end of the region do not match!)'), r, r->size, region_ceiling_size(r) == r->size); return 1; } @@ -432,7 +432,7 @@ static int validate_memory_regions() { Region *fr = freeRegionBuckets[i].next; while (fr != &freeRegionBuckets[i]) { if (!debug_region_is_consistent(fr) || !region_is_free(fr) || fr->prev != prev || fr->next == fr || fr->prev == fr) { - MAIN_THREAD_ASYNC_EM_ASM(out('In bucket '+$0+', free region '+ptrToString($1)+', size: ' + toString(Number($2)) + ' (size at ceiling: '+toString(Number($3))+'), prev: ' + ptrToString($4) + ', next: 0x' + ptrToString($5) + ' is corrupt!'), + MAIN_THREAD_ASYNC_EM_ASM(out('In bucket '+$0+', free region '+ptrToString($1)+', size: ' + Number($2) + ' (size at ceiling: '+Number($3)+'), prev: ' + ptrToString($4) + ', next: 0x' + ptrToString($5) + ' is corrupt!'), i, fr, fr->size, size_of_region_from_ceiling(fr), fr->prev, fr->next); return 1; } @@ -629,7 +629,7 @@ static void *attempt_allocate(Region *freeRegion, size_t alignment, size_t size) #endif #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('attempt_allocate - succeeded allocating memory, region ptr=' + ptrToString($0) + ', align=' + $1 + ', payload size=' + toString(Number($2)) + ' bytes)'), freeRegion, alignment, size); + MAIN_THREAD_ASYNC_EM_ASM(out('attempt_allocate - succeeded allocating memory, region ptr=' + ptrToString($0) + ', align=' + $1 + ', payload size=' + Number($2) + ' bytes)'), freeRegion, alignment, size); #endif return (uint8_t*)freeRegion + sizeof(size_t); @@ -659,7 +659,7 @@ static void *allocate_memory(size_t alignment, size_t size) { ASSERT_MALLOC_IS_ACQUIRED(); #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('allocate_memory(align=' + $0 + ', size=' + toString(Number($1)) + ' bytes)'), alignment, size); + MAIN_THREAD_ASYNC_EM_ASM(out('allocate_memory(align=' + $0 + ', size=' + Number($1) + ' bytes)'), alignment, size); #endif #ifdef EMMALLOC_MEMVALIDATE @@ -675,7 +675,7 @@ static void *allocate_memory(size_t alignment, size_t size) { if (size > MAX_ALLOC_SIZE) { #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + toString(Number($0)) + 'bytes! (negative integer wraparound?)'), size); + MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + Number($0) + 'bytes! (negative integer wraparound?)'), size); #endif return 0; } @@ -930,7 +930,7 @@ static int attempt_region_resize(Region *region, size_t size) { assert(HAS_ALIGNMENT(size, sizeof(size_t))); #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('attempt_region_resize(region=' + ptrToString($0) + ', size=' + toString(Number($1)) + ' bytes)'), region, size); + MAIN_THREAD_ASYNC_EM_ASM(out('attempt_region_resize(region=' + ptrToString($0) + ', size=' + Number($1) + ' bytes)'), region, size); #endif // First attempt to resize this region, if the next region that follows this one @@ -988,7 +988,7 @@ static int acquire_and_attempt_region_resize(Region *region, size_t size) { void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size) { #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('aligned_realloc(ptr=' + ptrToString($0) + ', alignment=' + $1 + ', size=' + toString(Number($2))), ptr, alignment, size); + MAIN_THREAD_ASYNC_EM_ASM(out('aligned_realloc(ptr=' + ptrToString($0) + ', alignment=' + $1 + ', size=' + Number($2)), ptr, alignment, size); #endif if (!ptr) { @@ -1002,7 +1002,7 @@ void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size) { if (size > MAX_ALLOC_SIZE) { #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + toString(Number($0)) + 'bytes! (negative integer wraparound?)'), size); + MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + Number($0) + 'bytes! (negative integer wraparound?)'), size); #endif return 0; } @@ -1052,7 +1052,7 @@ void *emmalloc_realloc_try(void *ptr, size_t size) { if (size > MAX_ALLOC_SIZE) { #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + toString(Number($0)) + 'bytes! (negative integer wraparound?)'), size); + MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + Number($0) + 'bytes! (negative integer wraparound?)'), size); #endif return 0; } @@ -1086,7 +1086,7 @@ void *emmalloc_aligned_realloc_uninitialized(void *ptr, size_t alignment, size_t if (size > MAX_ALLOC_SIZE) { #ifdef EMMALLOC_VERBOSE - MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + toString(Number($0)) + 'bytes! (negative integer wraparound?)'), size); + MAIN_THREAD_ASYNC_EM_ASM(out('Allocation failed: attempted allocation size is too large: ' + Number($0) + 'bytes! (negative integer wraparound?)'), size); #endif return 0; } From c95a67f0211f978dd5c4d95ee75d7327a85099ba Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 6 Dec 2024 10:59:32 +0100 Subject: [PATCH 2/5] `emmalloc-verbose` is compatible with wasm64 after 04a0cad --- test/test_core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_core.py b/test/test_core.py index fd18476c6ccea..8ecfd0e60949e 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -797,8 +797,6 @@ def test_mainenv(self): 'memvalidate_verbose': ['-DEMMALLOC_MEMVALIDATE', '-DEMMALLOC_VERBOSE', '-DRANDOM_ITERS=130'], }) def test_emmalloc(self, *args): - if '-DEMMALLOC_VERBOSE' in args and self.is_wasm64(): - self.skipTest('EMMALLOC_VERBOSE is not compatible with wasm64') # in newer clang+llvm, the internal calls to malloc in emmalloc may be optimized under # the assumption that they are external, so like in system_libs.py where we build # malloc, we need to disable builtin here too From 6fef505f12534572e0bca0b270a72e7e7b4731ab Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 6 Dec 2024 11:00:02 +0100 Subject: [PATCH 3/5] Add `maybe_closure()` regression test to `test_emmalloc` --- test/test_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_core.py b/test/test_core.py index 8ecfd0e60949e..33a1a81812a3a 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -797,6 +797,7 @@ def test_mainenv(self): 'memvalidate_verbose': ['-DEMMALLOC_MEMVALIDATE', '-DEMMALLOC_VERBOSE', '-DRANDOM_ITERS=130'], }) def test_emmalloc(self, *args): + self.maybe_closure() # in newer clang+llvm, the internal calls to malloc in emmalloc may be optimized under # the assumption that they are external, so like in system_libs.py where we build # malloc, we need to disable builtin here too From 6ac01fac91025f77cd1aecf1313b9835a10907f3 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 6 Dec 2024 12:08:41 +0100 Subject: [PATCH 4/5] Fix CI --- test/test_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_core.py b/test/test_core.py index 8ad5bd1ac531f..f1ed71f295c0b 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -798,6 +798,7 @@ def test_mainenv(self): }) def test_emmalloc(self, *args): self.maybe_closure() + self.set_setting('DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', ['$ptrToString']) # in newer clang+llvm, the internal calls to malloc in emmalloc may be optimized under # the assumption that they are external, so like in system_libs.py where we build # malloc, we need to disable builtin here too From 81182932afcd553adaded8e4a7d9663cbf4861a6 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 6 Dec 2024 19:11:42 +0100 Subject: [PATCH 5/5] emmalloc: Ensure `$ptrToString` is always available Required by `emmalloc_{dump,validate}_memory_regions()`. --- system/lib/emmalloc.c | 2 -- test/test_core.py | 1 - 2 files changed, 3 deletions(-) diff --git a/system/lib/emmalloc.c b/system/lib/emmalloc.c index 0451f6f7a5ce8..a2156e620fa40 100644 --- a/system/lib/emmalloc.c +++ b/system/lib/emmalloc.c @@ -651,9 +651,7 @@ static size_t validate_alloc_size(size_t size) { return validatedSize; } -#ifdef EMMALLOC_VERBOSE EM_JS_DEPS(deps, "$ptrToString"); -#endif static void *allocate_memory(size_t alignment, size_t size) { ASSERT_MALLOC_IS_ACQUIRED(); diff --git a/test/test_core.py b/test/test_core.py index f1ed71f295c0b..8ad5bd1ac531f 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -798,7 +798,6 @@ def test_mainenv(self): }) def test_emmalloc(self, *args): self.maybe_closure() - self.set_setting('DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', ['$ptrToString']) # in newer clang+llvm, the internal calls to malloc in emmalloc may be optimized under # the assumption that they are external, so like in system_libs.py where we build # malloc, we need to disable builtin here too