Skip to content

Commit 85f0296

Browse files
authored
Fix emmalloc tests to allow a bit of slop (#10183)
* Add debugging for initial heap sizes * Fix emmalloc tests to have a 4k slop for varying memory heap sizes. Skip emmalloc tests in LSan and ASan which do not support custom memory allocators.
1 parent f93823e commit 85f0296

File tree

7 files changed

+90
-140
lines changed

7 files changed

+90
-140
lines changed

system/lib/emmalloc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,10 @@ static int acquire_and_attempt_region_resize(Region *region, size_t size)
10271027

10281028
void *emmalloc_aligned_realloc(void *ptr, size_t alignment, size_t size)
10291029
{
1030+
#ifdef EMMALLOC_DEBUG_LOG
1031+
MAIN_THREAD_ASYNC_EM_ASM(console.log('aligned_realloc(ptr=' + $0.toString(16) + ', alignment=' + $1 + ', size=' + $2), ptr, alignment, size);
1032+
#endif
1033+
10301034
if (!ptr)
10311035
return emmalloc_memalign(alignment, size);
10321036

tests/core/test_emmalloc.cpp

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,12 @@
1616

1717
extern "C" void emmalloc_blank_slate_from_orbit();
1818

19-
// Test emmalloc internals, but through the external interface. We expect
20-
// very specific outputs here based on the internals, this test would not
21-
// pass in another malloc.
22-
23-
void* check_where_we_would_malloc(size_t size) {
24-
void* temp = malloc(size);
25-
free(temp);
26-
return temp;
27-
}
28-
29-
void check_where_we_would_malloc(size_t size, void* expected) {
30-
void* temp = malloc(size);
31-
assert(temp == expected);
32-
free(temp);
33-
}
34-
3519
void stage(const char* name) {
3620
EM_ASM({
3721
out('\n>> ' + UTF8ToString($0) + '\n');
3822
}, name);
3923
}
4024

41-
const size_t ALLOCATION_UNIT = 8;
42-
4325
void basics() {
4426
stage("basics");
4527
stage("allocate 0");
@@ -55,83 +37,30 @@ void basics() {
5537
stage("allocate 10");
5638
assert(second == first);
5739
void* third = malloc(10);
58-
assert(size_t(third) == size_t(first) + ((100 + ALLOCATION_UNIT - 1)&(-ALLOCATION_UNIT)) + ALLOCATION_UNIT); // allocation units are multiples of ALLOCATION_UNIT
40+
assert(!emmalloc_validate_memory_regions());
5941
stage("allocate 10 more");
6042
void* four = malloc(10);
61-
assert(size_t(four) == size_t(third) + (2*ALLOCATION_UNIT) + ALLOCATION_UNIT); // payload (10 = 2 allocation units) and metadata
43+
assert(!emmalloc_validate_memory_regions());
6244
stage("free the first");
6345
free(second);
64-
stage("several temp alloc/frees");
65-
// we reuse the first area, despite stuff later.
66-
for (int i = 0; i < 4; i++) {
67-
check_where_we_would_malloc(100, first);
68-
}
6946
stage("free all");
7047
free(third);
7148
free(four);
72-
stage("allocate various sizes to see they all start at the start");
73-
for (int i = 1; i < 1500; i++) {
74-
check_where_we_would_malloc(i, first);
75-
}
76-
}
77-
78-
void blank_slate() {
79-
stage("blank_slate");
80-
emmalloc_blank_slate_from_orbit();
81-
void* ptr = malloc(0);
82-
free(ptr);
83-
for (int i = 0; i < 3; i++) {
84-
void* two = malloc(0);
85-
assert(two == ptr);
86-
free(two);
87-
}
88-
for (int i = 0; i < 3; i++) {
89-
emmalloc_blank_slate_from_orbit();
90-
void* two = malloc(0);
91-
// emmalloc_blank_slate_from_orbit clears out the free list without freeing the blocks on it
92-
// Effectively, memory is leaked and we do not expect the pointers to be the same
93-
assert(two != ptr);
94-
free(two);
95-
}
49+
assert(!emmalloc_validate_memory_regions());
9650
}
9751

9852
void previous_sbrk() {
9953
stage("previous_sbrk");
10054
emmalloc_blank_slate_from_orbit();
10155
void* old = sbrk(0);
102-
assert((size_t)old % ALLOCATION_UNIT == 0);
56+
assert((size_t)old % 4 == 0);
10357
sbrk(3); // unalign things
10458
void* other = malloc(10);
10559
free(other);
10660
assert(other != old);
10761
}
10862

109-
void min_alloc() {
110-
stage("min_alloc");
111-
emmalloc_blank_slate_from_orbit();
112-
void* start = check_where_we_would_malloc(1);
113-
for (int i = 1; i < 100; i++) {
114-
void* temp = malloc(i);
115-
void* expected = (char*)start + ALLOCATION_UNIT + ALLOCATION_UNIT * ((i + ALLOCATION_UNIT - 1) / ALLOCATION_UNIT);
116-
check_where_we_would_malloc(1, expected);
117-
free(temp);
118-
}
119-
}
120-
121-
void space_at_end() {
122-
stage("space_at_end");
123-
emmalloc_blank_slate_from_orbit();
124-
void* start = check_where_we_would_malloc(1);
125-
for (int i = 1; i < 50; i++) {
126-
for (int j = 1; j < 50; j++) {
127-
void* temp = malloc(i);
128-
free(temp);
129-
check_where_we_would_malloc(j, start);
130-
}
131-
}
132-
}
133-
134-
void calloc() {
63+
void test_calloc() {
13564
stage("calloc");
13665
emmalloc_blank_slate_from_orbit();
13766
char* ptr = (char*)malloc(10);
@@ -142,7 +71,7 @@ void calloc() {
14271
assert(ptr[0] == 0);
14372
}
14473

145-
void realloc() {
74+
void test_realloc() {
14675
stage("realloc0");
14776
emmalloc_blank_slate_from_orbit();
14877
for (int i = 0; i < 2; i++) {
@@ -168,18 +97,16 @@ void realloc() {
16897
}
16998
stage("realloc1");
17099
emmalloc_blank_slate_from_orbit();
171-
{
172-
// realloc of NULL is like malloc
173-
void* ptr = check_where_we_would_malloc(10);
174-
assert(realloc(NULL, 10) == ptr);
175-
}
100+
101+
// realloc of NULL is like malloc
102+
assert(realloc(NULL, 10) != 0);
103+
176104
stage("realloc2");
177105
emmalloc_blank_slate_from_orbit();
178106
{
179107
// realloc to 0 is like free
180108
void* ptr = malloc(10);
181109
assert(realloc(ptr, 0) == NULL);
182-
assert(check_where_we_would_malloc(10) == ptr);
183110
}
184111
stage("realloc3");
185112
emmalloc_blank_slate_from_orbit();
@@ -230,7 +157,7 @@ void aligned() {
230157
void randoms() {
231158
stage("randoms");
232159
emmalloc_blank_slate_from_orbit();
233-
void* start = check_where_we_would_malloc(10);
160+
void* start = malloc(10);
234161
const int N = 1000;
235162
const int BINS = 128;
236163
void* bins[BINS];
@@ -285,20 +212,16 @@ void randoms() {
285212
for (int i = 0; i < BINS; i++) {
286213
if (bins[i]) free(bins[i]);
287214
}
288-
// it's all freed, should be a blank slate
289-
assert(check_where_we_would_malloc(10) == start);
215+
assert(!emmalloc_validate_memory_regions());
290216
}
291217

292218
int main() {
293219
stage("beginning");
294220

295221
basics();
296-
blank_slate();
297222
previous_sbrk();
298-
min_alloc();
299-
space_at_end();
300-
calloc();
301-
realloc();
223+
test_calloc();
224+
test_realloc();
302225
aligned();
303226
randoms();
304227

tests/core/test_emmalloc_memory_statistics.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include <stdio.h>
22
#include <emscripten/emmalloc.h>
33

4+
template<typename T>
5+
T round_to_4k(T val){
6+
return (T)(((size_t)val + 4095) & ~4095);
7+
}
8+
49
int main()
510
{
611
void *ptr = malloc(32*1024*1024);
@@ -21,5 +26,5 @@ int main()
2126
for(int i = 0; i < 32; ++i)
2227
printf("%zu ", freeMemorySizeMap[i]);
2328
printf("\n");
24-
printf("%zu\n", emmalloc_unclaimed_heap_memory());
29+
printf("%zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
2530
}

tests/core/test_emmalloc_memory_statistics.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
4210892
55
3
66
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
7-
21997632
7+
21999616

tests/core/test_emmalloc_trim.cpp

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,60 @@
33
#include <emscripten/emmalloc.h>
44
#include <emscripten/heap.h>
55

6+
template<typename T>
7+
T round_to_4k(T val){
8+
return (T)(((size_t)val + 4095) & ~4095);
9+
}
10+
611
int main()
712
{
813
printf("heap size: %zu\n", emscripten_get_heap_size());
14+
printf("dynamic heap 0: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
15+
printf("free dynamic memory 0: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
16+
printf("unclaimed heap memory 0: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
17+
printf("sbrk 0: %p\n", round_to_4k(sbrk(0)));
918

1019
void *ptr = malloc(32*1024*1024);
1120
void *ptr2 = malloc(4*1024*1024);
1221
printf("%d\n", (int)(ptr && ptr2));
13-
printf("dynamic heap 1: %zu\n", emmalloc_dynamic_heap_size());
14-
printf("free dynamic memory 1: %zu\n", emmalloc_free_dynamic_memory());
15-
printf("unclaimed heap memory 1: %zu\n", emmalloc_unclaimed_heap_memory());
16-
printf("sbrk 1: %p\n", sbrk(0));
22+
printf("dynamic heap 1: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
23+
printf("free dynamic memory 1: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
24+
printf("unclaimed heap memory 1: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
25+
printf("sbrk 1: %p\n", round_to_4k(sbrk(0)));
1726

1827
int success = emmalloc_trim(0);
1928
printf("1st trim: %d\n", success);
20-
printf("dynamic heap 1: %zu\n", emmalloc_dynamic_heap_size());
21-
printf("free dynamic memory 1: %zu\n", emmalloc_free_dynamic_memory());
22-
printf("unclaimed heap memory 1: %zu\n", emmalloc_unclaimed_heap_memory());
23-
printf("sbrk 1: %p\n", sbrk(0));
29+
printf("dynamic heap 1: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
30+
printf("free dynamic memory 1: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
31+
printf("unclaimed heap memory 1: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
32+
printf("sbrk 1: %p\n", round_to_4k(sbrk(0)));
2433

2534
success = emmalloc_trim(0);
2635
printf("2nd trim: %d\n", success);
27-
printf("dynamic heap 2: %zu\n", emmalloc_dynamic_heap_size());
28-
printf("free dynamic memory 2: %zu\n", emmalloc_free_dynamic_memory());
29-
printf("unclaimed heap memory 2: %zu\n", emmalloc_unclaimed_heap_memory());
30-
printf("sbrk 2: %p\n", sbrk(0));
36+
printf("dynamic heap 2: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
37+
printf("free dynamic memory 2: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
38+
printf("unclaimed heap memory 2: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
39+
printf("sbrk 2: %p\n", round_to_4k(sbrk(0)));
3140
free(ptr2);
3241

3342
success = emmalloc_trim(100000);
3443
printf("3rd trim: %d\n", success);
35-
printf("dynamic heap 3: %zu\n", emmalloc_dynamic_heap_size());
36-
printf("free dynamic memory 3: %zu\n", emmalloc_free_dynamic_memory());
37-
printf("unclaimed heap memory 3: %zu\n", emmalloc_unclaimed_heap_memory());
38-
printf("sbrk 3: %p\n", sbrk(0));
44+
printf("dynamic heap 3: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
45+
printf("free dynamic memory 3: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
46+
printf("unclaimed heap memory 3: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
47+
printf("sbrk 3: %p\n", round_to_4k(sbrk(0)));
3948

4049
success = emmalloc_trim(100000);
4150
printf("4th trim: %d\n", success);
42-
printf("dynamic heap 4: %zu\n", emmalloc_dynamic_heap_size());
43-
printf("free dynamic memory 4: %zu\n", emmalloc_free_dynamic_memory());
44-
printf("unclaimed heap memory 4: %zu\n", emmalloc_unclaimed_heap_memory());
45-
printf("sbrk 4: %p\n", sbrk(0));
51+
printf("dynamic heap 4: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
52+
printf("free dynamic memory 4: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
53+
printf("unclaimed heap memory 4: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
54+
printf("sbrk 4: %p\n", round_to_4k(sbrk(0)));
4655

4756
success = emmalloc_trim(0);
4857
printf("5th trim: %d\n", success);
49-
printf("dynamic heap 5: %zu\n", emmalloc_dynamic_heap_size());
50-
printf("free dynamic memory 5: %zu\n", emmalloc_free_dynamic_memory());
51-
printf("unclaimed heap memory 5: %zu\n", emmalloc_unclaimed_heap_memory());
52-
printf("sbrk 5: %p\n", sbrk(0));
58+
printf("dynamic heap 5: %zu\n", round_to_4k(emmalloc_dynamic_heap_size()));
59+
printf("free dynamic memory 5: %zu\n", round_to_4k(emmalloc_free_dynamic_memory()));
60+
printf("unclaimed heap memory 5: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
61+
printf("sbrk 5: %p\n", round_to_4k(sbrk(0)));
5362
}

tests/core/test_emmalloc_trim.txt

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
heap size: 134217728
2+
dynamic heap 0: 4096
3+
free dynamic memory 0: 4096
4+
unclaimed heap memory 0: 2142171136
5+
sbrk 0: 0x502000
26
1
3-
dynamic heap 1: 37748880
4-
free dynamic memory 1: 84
5-
unclaimed heap memory 1: 2104421504
6-
sbrk 1: 0x2901380
7+
dynamic heap 1: 37752832
8+
free dynamic memory 1: 4096
9+
unclaimed heap memory 1: 2104422400
10+
sbrk 1: 0x2902000
711
1st trim: 1
8-
dynamic heap 1: 37748788
12+
dynamic heap 1: 37752832
913
free dynamic memory 1: 0
10-
unclaimed heap memory 1: 2104421596
11-
sbrk 1: 0x2901324
14+
unclaimed heap memory 1: 2104422400
15+
sbrk 1: 0x2902000
1216
2nd trim: 0
13-
dynamic heap 2: 37748788
17+
dynamic heap 2: 37752832
1418
free dynamic memory 2: 0
15-
unclaimed heap memory 2: 2104421596
16-
sbrk 2: 0x2901324
19+
unclaimed heap memory 2: 2104422400
20+
sbrk 2: 0x2902000
1721
3rd trim: 1
18-
dynamic heap 3: 33654492
19-
free dynamic memory 3: 100008
20-
unclaimed heap memory 3: 2108515892
21-
sbrk 3: 0x25199cc
22+
dynamic heap 3: 33656832
23+
free dynamic memory 3: 102400
24+
unclaimed heap memory 3: 2108518400
25+
sbrk 3: 0x251a000
2226
4th trim: 0
23-
dynamic heap 4: 33654492
24-
free dynamic memory 4: 100008
25-
unclaimed heap memory 4: 2108515892
26-
sbrk 4: 0x25199cc
27+
dynamic heap 4: 33656832
28+
free dynamic memory 4: 102400
29+
unclaimed heap memory 4: 2108518400
30+
sbrk 4: 0x251a000
2731
5th trim: 1
28-
dynamic heap 5: 33554476
32+
dynamic heap 5: 33558528
2933
free dynamic memory 5: 0
30-
unclaimed heap memory 5: 2108615908
31-
sbrk 5: 0x250131c
34+
unclaimed heap memory 5: 2108616704
35+
sbrk 5: 0x2502000

0 commit comments

Comments
 (0)