Skip to content

Commit 22ac53a

Browse files
committed
Reduce default stack size from 5Mb to 64Kb
See ChangeLog.md for rationale.
1 parent b232947 commit 22ac53a

File tree

10 files changed

+57
-42
lines changed

10 files changed

+57
-42
lines changed

ChangeLog.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ See docs/process.md for more on how version tagging works.
3131
overflow will trap rather corrupting global data first). This should not
3232
be a user-visible change (unless your program does something very odd such
3333
depending on the specific location of stack data in memory). (#18154)
34+
- Default value for `STACK_SIZE` (the size of the wasm shadow stack) was reduced
35+
from 5Mb to 64Mb. Project that use more that 64Kb of stack will now have to
36+
start specifying `-sSTACK_SIZE` at link time. To aid in debugging, as of
37+
#18154, we now also place the stack first in memory in debug builds so that
38+
overflows will be immediately detected, and result in runtime errors.
39+
This change brings emscripten into line with wasm-ld and wasi-sdk defaults.
40+
In general, WebAssembly stack usage should be lower than on other platforms
41+
since a lot of state normally stores on the stack is hidden from the runtime
42+
and doesn't use the shadow stack at all.
43+
The default for `DEFAULT_PTHREAD_STACK_SIZE` was also reduced from 2Mb to 64Kb
44+
to match.
3445

3546
3.1.25 - 11/08/22
3647
-----------------

src/library.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3142,12 +3142,14 @@ mergeInto(LibraryManager.library, {
31423142
#if STACK_OVERFLOW_CHECK
31433143
// Used by wasm-emscripten-finalize to implement STACK_OVERFLOW_CHECK
31443144
__handle_stack_overflow__sig: 'vp',
3145-
__handle_stack_overflow__deps: ['emscripten_stack_get_base'],
3145+
__handle_stack_overflow__deps: ['emscripten_stack_get_base', 'emscripten_stack_get_end', '$ptrToString'],
31463146
__handle_stack_overflow: function(requested) {
31473147
requested = requested >>> 0;
3148+
var base = _emscripten_stack_get_base();
3149+
var end = _emscripten_stack_get_end();
31483150
abort('stack overflow (Attempt to set SP to ' + ptrToString(requested) +
3149-
', with stack limits [' + ptrToString(_emscripten_stack_get_end()) +
3150-
' - ' + ptrToString(_emscripten_stack_get_base()) + '])');
3151+
', with stack limits [' + ptrToString(end) + ' - ' + ptrToString(base) +
3152+
']). If you require more stack space build with -sSTACK_SIZE=<bytes>');
31513153
},
31523154
#endif
31533155

src/settings.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ var MEM_INIT_METHOD = false;
110110
// assertions are on, we will assert on not exceeding this, otherwise,
111111
// it will fail silently.
112112
// [link]
113-
var STACK_SIZE = 5*1024*1024;
113+
var STACK_SIZE = 64*1024;
114114

115115
// What malloc()/free() to use, out of
116116
// * dlmalloc - a powerful general-purpose malloc
@@ -1592,7 +1592,7 @@ var PTHREAD_POOL_DELAY_LOAD = false;
15921592
// those that have their addresses taken, or ones that are too large to fit as
15931593
// local vars in wasm code.
15941594
// [link]
1595-
var DEFAULT_PTHREAD_STACK_SIZE = 2*1024*1024;
1595+
var DEFAULT_PTHREAD_STACK_SIZE = 64*1024;
15961596

15971597
// True when building with --threadprofiler
15981598
// [link]

test/core/test_emmalloc_memory_statistics.cpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,29 @@
22
#include <emscripten/emmalloc.h>
33

44
template<typename T>
5-
T round_to_4k(T val) {
6-
return (T)(((size_t)val + 4095) & ~4095);
5+
T round_to_4k(T val){
6+
return (T)(((size_t)val + 4095) & ~4095);
77
}
88

9-
int main() {
10-
void *ptr = malloc(32*1024*1024);
11-
void *ptr2 = malloc(4*1024*1024);
12-
void *ptr3 = malloc(64*1024*1024);
13-
void *ptr4 = malloc(16*1024);
14-
void *ptr5 = malloc(2*1024*1024);
15-
printf("%ld\n", (long)(ptr && ptr2 && ptr3 && ptr4 && ptr5));
16-
free(ptr2);
17-
free(ptr4);
18-
printf("validate_memory_regions: %d\n", emmalloc_validate_memory_regions());
19-
printf("dynamic_heap_size: %zu\n", emmalloc_dynamic_heap_size());
20-
printf("free_dynamic_memory: %zu\n", emmalloc_free_dynamic_memory());
21-
size_t numFreeMemoryRegions = 0;
22-
size_t freeMemorySizeMap[32];
23-
numFreeMemoryRegions = emmalloc_compute_free_dynamic_memory_fragmentation_map(freeMemorySizeMap);
24-
printf("numFreeMemoryRegions: %zu\n", numFreeMemoryRegions);
25-
for (int i = 0; i < 32; ++i) {
26-
printf("%zu ", freeMemorySizeMap[i]);
27-
}
28-
printf("\n");
29-
printf("unclaimed_heap_memory: %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
30-
return 0;
9+
int main()
10+
{
11+
void *ptr = malloc(32*1024*1024);
12+
void *ptr2 = malloc(4*1024*1024);
13+
void *ptr3 = malloc(64*1024*1024);
14+
void *ptr4 = malloc(16*1024);
15+
void *ptr5 = malloc(2*1024*1024);
16+
printf("valid allocs: %d\n", (int)(ptr && ptr2 && ptr3 && ptr4 && ptr5));
17+
free(ptr2);
18+
free(ptr4);
19+
printf("emmalloc_validate_memory_regions: %d\n", emmalloc_validate_memory_regions());
20+
printf("emmalloc_dynamic_heap_size : %zu\n", emmalloc_dynamic_heap_size());
21+
printf("emmalloc_free_dynamic_memory : %zu\n", emmalloc_free_dynamic_memory());
22+
size_t numFreeMemoryRegions = 0;
23+
size_t freeMemorySizeMap[32];
24+
numFreeMemoryRegions = emmalloc_compute_free_dynamic_memory_fragmentation_map(freeMemorySizeMap);
25+
printf("numFreeMemoryRegions: %zu\n", numFreeMemoryRegions);
26+
for(int i = 0; i < 32; ++i)
27+
printf("%zu ", freeMemorySizeMap[i]);
28+
printf("\n");
29+
printf("emmalloc_unclaimed_heap_memory : %zu\n", round_to_4k(emmalloc_unclaimed_heap_memory()));
3130
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
1
2-
validate_memory_regions: 0
3-
dynamic_heap_size: 106971424
4-
free_dynamic_memory: 4210892
1+
valid allocs: 1
2+
emmalloc_validate_memory_regions: 0
3+
emmalloc_dynamic_heap_size : 106971424
4+
emmalloc_free_dynamic_memory : 4210892
55
numFreeMemoryRegions: 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-
unclaimed_heap_memory: 21999616
7+
emmalloc_unclaimed_heap_memory : 27176960

test/core/test_memcpy3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
int main() {
2727
#define RUN(type) \
2828
{ \
29-
type buffer[TOTAL]; \
29+
static type buffer[TOTAL]; \
3030
volatile int seed = 123; \
3131
TEST(1, type); \
3232
TEST(2, type); \
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Heap size before allocation: 16777216
2-
Ptr: 1, value: 16843009, Heap size now: 101777408 (increase: 85000192 bytes)
2+
Ptr: 1, value: 16843009, Heap size now: 96600064 (increase: 79822848 bytes)

test/core/test_memset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
int main() {
2727
#define RUN(type) \
2828
{ \
29-
type buffer[TOTAL]; \
29+
static type buffer[TOTAL]; \
3030
volatile int seed = 123; \
3131
TEST(1, type); \
3232
TEST(2, type); \

test/fs/test_mmap.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,12 @@ void test_mmap_shared_with_offset() {
180180
assert(fd >= 0);
181181
size_t offset = sysconf(_SC_PAGE_SIZE) * 2;
182182

183-
char buffer[offset + 33];
184-
memset(buffer, 0, offset + 33);
185-
fread(buffer, 1, offset + 32, fd);
183+
char buffer[33];
184+
memset(buffer, 0, 33);
185+
fseek(fd, offset, SEEK_SET);
186+
fread(buffer, 1, 32, fd);
186187
// expect text written from mmap operation to appear at offset in the file
187-
printf("yolo/sharedoffset.txt content=%s %zu\n", buffer + offset, offset);
188+
printf("yolo/sharedoffset.txt content=%s %zu\n", buffer, offset);
188189
fclose(fd);
189190
}
190191
}

test/test_other.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,8 @@ def test_embind(self, extra_args):
26202620
'--pre-js', test_file('embind/test.pre.js'),
26212621
'--post-js', test_file('embind/test.post.js'),
26222622
'-sWASM_ASYNC_COMPILATION=0',
2623+
# The default stack size is not enough for these tests.
2624+
'-sTOTAL_STACK=2Mb',
26232625
'-sIN_TEST_HARNESS'] + args)
26242626

26252627
if '-sDYNAMIC_EXECUTION=0' in args:
@@ -5818,7 +5820,7 @@ def test_massive_alloc(self, wasm):
58185820
# just care about message regarding allocating over 1GB of memory
58195821
output = self.run_js('a.out.js')
58205822
if not wasm:
5821-
self.assertContained('Warning: Enlarging memory arrays, this is not fast! 16777216,1473314816\n', output)
5823+
self.assertContained('Warning: Enlarging memory arrays, this is not fast! 16777216,1468137472\n', output)
58225824

58235825
def test_failing_alloc(self):
58245826
for pre_fail, post_fail, opts in [

0 commit comments

Comments
 (0)