Skip to content

Commit 22a1c04

Browse files
Initial new INITIAL_HEAP setting (#21071)
Changes in default behavior: 1) INITIAL_HEAP is the new default for most builds. This means that there is an increase in the effective initial memory used by "sizeof(stack) + sizeof(static data)". In typical small applications this should be on the order of half a megabyte. 2) Because we cannot precisely calculate the amount of initial memory now, ASAN support will use the conservative upper estimate of MAXIMUM_MEMORY. This only affects ALLOW_MEMORY_GROWTH=0 builds. This change does not yet enable INITIAL_HEAP for builds that instantiate the memory in JS, e. g. with threading.
1 parent e8262f6 commit 22a1c04

File tree

11 files changed

+167
-47
lines changed

11 files changed

+167
-47
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ See docs/process.md for more on how version tagging works.
2929
data into an external .mem file). This feature was only available under
3030
wasm2js (`-sWASM=0`) anyway so this change will only affect users of this
3131
setting. (#21217)
32+
- `INITIAL_HEAP` setting is introduced to control the amount of initial
33+
memory available for dynamic allocation without capping it. If you are
34+
using `INITIAL_MEMORY`, consider switching to `INITIAL_HEAP`. Note that
35+
it is currently not supported in all configurations (#21071).
3236

3337
3.1.54 - 02/15/24
3438
-----------------

site/source/docs/tools_reference/settings_reference.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ Note that this setting does not affect the behavior of operator new in C++.
151151
This function will always abort on allocation failure if exceptions are disabled.
152152
If you want new to return 0 on failure, use it with std::nothrow.
153153

154+
.. _initial_heap:
155+
156+
INITIAL_HEAP
157+
============
158+
159+
The initial amount of heap memory available to the program. This is the
160+
memory region available for dynamic allocations via `sbrk`, `malloc` and `new`.
161+
162+
Unlike INITIAL_MEMORY, this setting allows the static and dynamic regions of
163+
your programs memory to independently grow. In most cases we recommend using
164+
this setting rather than `INITIAL_MEMORY`. However, this setting does not work
165+
for imported memories (e.g. when dynamic linking is used).
166+
154167
.. _initial_memory:
155168

156169
INITIAL_MEMORY
@@ -162,6 +175,9 @@ we need to copy the old heap into a new one in that case.
162175
If ALLOW_MEMORY_GROWTH is set, this initial amount of memory can increase
163176
later; if not, then it is the final and total amount of memory.
164177

178+
By default, this value is calculated based on INITIAL_HEAP, STACK_SIZE,
179+
as well the size of static data in input modules.
180+
165181
(This option was formerly called TOTAL_MEMORY.)
166182

167183
.. _maximum_memory:

src/postamble_minimal.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ WebAssembly.instantiate(Module['wasm'], imports).then((output) => {
216216
wasmMemory = wasmExports['memory'];
217217
#if ASSERTIONS
218218
assert(wasmMemory);
219-
assert(wasmMemory.buffer.byteLength === {{{ INITIAL_MEMORY }}});
220219
#endif
221220
updateMemoryViews();
222221
#endif

src/preamble.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,6 @@ function createWasm() {
966966
{{{ receivedSymbol('wasmMemory') }}}
967967
#if ASSERTIONS
968968
assert(wasmMemory, 'memory not found in wasm exports');
969-
// This assertion doesn't hold when emscripten is run in --post-link
970-
// mode.
971-
// TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode.
972-
//assert(wasmMemory.buffer.byteLength === {{{ INITIAL_MEMORY }}});
973969
#endif
974970
updateMemoryViews();
975971
#endif

src/settings.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,29 @@ var MALLOC = "dlmalloc";
154154
// [link]
155155
var ABORTING_MALLOC = true;
156156

157+
// The initial amount of heap memory available to the program. This is the
158+
// memory region available for dynamic allocations via `sbrk`, `malloc` and `new`.
159+
//
160+
// Unlike INITIAL_MEMORY, this setting allows the static and dynamic regions of
161+
// your programs memory to independently grow. In most cases we recommend using
162+
// this setting rather than `INITIAL_MEMORY`. However, this setting does not work
163+
// for imported memories (e.g. when dynamic linking is used).
164+
//
165+
// [link]
166+
var INITIAL_HEAP = 16777216;
167+
157168
// The initial amount of memory to use. Using more memory than this will
158169
// cause us to expand the heap, which can be costly with typed arrays:
159170
// we need to copy the old heap into a new one in that case.
160171
// If ALLOW_MEMORY_GROWTH is set, this initial amount of memory can increase
161172
// later; if not, then it is the final and total amount of memory.
162173
//
174+
// By default, this value is calculated based on INITIAL_HEAP, STACK_SIZE,
175+
// as well the size of static data in input modules.
176+
//
163177
// (This option was formerly called TOTAL_MEMORY.)
164178
// [link]
165-
var INITIAL_MEMORY = 16777216;
179+
var INITIAL_MEMORY = -1;
166180

167181
// Set the maximum size of memory in the wasm module (in bytes). This is only
168182
// relevant when ALLOW_MEMORY_GROWTH is set, as without growth, the size of

test/code_size/hello_world_wasm2js.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function e(b) {
2121
m[43] = 62;
2222
m[47] = 63;
2323
return function(c) {
24-
var a = new ArrayBuffer(16777216), f = new Uint8Array(a), v = c.a.a;
24+
var a = new ArrayBuffer(16908288), f = new Uint8Array(a), v = c.a.a;
2525
q = f;
2626
x(q, 1024, "aGVsbG8h");
2727
c = u([]);

test/test_core.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ def test_memorygrowth_geometric_step(self):
21082108
if self.is_wasm2js():
21092109
self.skipTest('wasm memory specific test')
21102110

2111-
self.emcc_args += ['-sALLOW_MEMORY_GROWTH', '-sMEMORY_GROWTH_GEOMETRIC_STEP=8.5', '-sMEMORY_GROWTH_GEOMETRIC_CAP=32MB']
2111+
self.emcc_args += ['-sINITIAL_MEMORY=16MB', '-sALLOW_MEMORY_GROWTH', '-sMEMORY_GROWTH_GEOMETRIC_STEP=8.5', '-sMEMORY_GROWTH_GEOMETRIC_CAP=32MB']
21122112
self.do_core_test('test_memorygrowth_geometric_step.c')
21132113

21142114
def test_memorygrowth_3_force_fail_reallocBuffer(self):
@@ -6006,6 +6006,7 @@ def test_unistd_sysconf_phys_pages(self):
60066006
assert self.get_setting('INITIAL_MEMORY') == '2200mb'
60076007
expected = (2200 * 1024 * 1024) // webassembly.WASM_PAGE_SIZE
60086008
else:
6009+
self.set_setting('INITIAL_MEMORY', '16mb')
60096010
expected = 16 * 1024 * 1024 // webassembly.WASM_PAGE_SIZE
60106011
self.do_runf(filename, str(expected) + ', errno: 0')
60116012

test/test_other.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6560,7 +6560,7 @@ def test_massive_alloc(self, wasm):
65606560
return x == 0; // can't alloc it, but don't fail catastrophically, expect null
65616561
}
65626562
''')
6563-
cmd = [EMCC, 'main.c', '-sALLOW_MEMORY_GROWTH']
6563+
cmd = [EMCC, 'main.c', '-sALLOW_MEMORY_GROWTH', '-sINITIAL_MEMORY=16MB']
65646564
if not wasm:
65656565
cmd += ['-sWASM=0']
65666566
self.run_process(cmd)
@@ -6619,7 +6619,7 @@ def test_failing_alloc(self):
66196619
printf("managed another malloc!\n");
66206620
}
66216621
''' % (pre_fail, post_fail))
6622-
args = [EMXX, 'main.cpp', '-sEXPORTED_FUNCTIONS=_main,_sbrk'] + opts + aborting_args
6622+
args = [EMXX, 'main.cpp', '-sEXPORTED_FUNCTIONS=_main,_sbrk', '-sINITIAL_MEMORY=16MB'] + opts + aborting_args
66236623
args += ['-sTEST_MEMORY_GROWTH_FAILS'] # In this test, force memory growing to fail
66246624
if growth:
66256625
args += ['-sALLOW_MEMORY_GROWTH']
@@ -8154,6 +8154,29 @@ def test_binaryen_warn_mem(self):
81548154
self.run_process([EMCC, test_file('hello_world.c'), '-sINITIAL_MEMORY=' + str(16 * 1024 * 1024), '--pre-js', 'pre.js', '-sALLOW_MEMORY_GROWTH', '-sWASM_ASYNC_COMPILATION=0', '-sIMPORTED_MEMORY'])
81558155
self.assertContained('hello, world!', self.run_js('a.out.js'))
81568156

8157+
@parameterized({
8158+
'': ([], 16 * 1024 * 1024), # Default behavior: 16MB initial heap
8159+
'explicit': (['-sINITIAL_HEAP=64KB'], 64 * 1024), # Explicitly set initial heap is passed
8160+
'with_initial_memory': (['-sINITIAL_MEMORY=40MB'], 0), # Backwards compatibility: no initial heap (we can't tell if it'll fit)
8161+
'with_maximum_memory': (['-sMAXIMUM_MEMORY=40MB', '-sALLOW_MEMORY_GROWTH=1'], 0), # Backwards compatibility: no initial heap (we can't tell if it'll fit)
8162+
'with_all': (['-sINITIAL_HEAP=128KB', '-sINITIAL_MEMORY=20MB', '-sMAXIMUM_MEMORY=40MB', '-sALLOW_MEMORY_GROWTH=1'], 128 * 1024),
8163+
'limited_by_initial_memory': (['-sINITIAL_HEAP=10MB', '-sINITIAL_MEMORY=10MB'], None), # Not enough space for stack
8164+
'limited_by_maximum_memory': (['-sINITIAL_HEAP=5MB', '-sMAXIMUM_MEMORY=5MB', '-sALLOW_MEMORY_GROWTH=1'], None), # Not enough space for stack
8165+
})
8166+
def test_initial_heap(self, args, expected_initial_heap):
8167+
cmd = [EMCC, test_file('hello_world.c'), '-v'] + args
8168+
8169+
if expected_initial_heap is None:
8170+
out = self.expect_fail(cmd)
8171+
self.assertContained('wasm-ld: error:', out)
8172+
return
8173+
8174+
out = self.run_process(cmd, stderr=PIPE)
8175+
if expected_initial_heap != 0:
8176+
self.assertContained(f'--initial-heap={expected_initial_heap}', out.stderr)
8177+
else:
8178+
self.assertNotContained('--initial-heap=', out.stderr)
8179+
81578180
def test_memory_size(self):
81588181
for args, expect_initial, expect_max in [
81598182
([], 320, 320),
@@ -8183,6 +8206,9 @@ def test_invalid_mem(self):
81838206
self.assertContained('hello, world!', self.run_js('a.out.js'))
81848207

81858208
# Must be a multiple of 64KB
8209+
ret = self.expect_fail([EMCC, test_file('hello_world.c'), '-sINITIAL_HEAP=32505857', '-sALLOW_MEMORY_GROWTH']) # 31MB + 1 byte
8210+
self.assertContained('INITIAL_HEAP must be a multiple of WebAssembly page size (64KiB)', ret)
8211+
81868212
ret = self.expect_fail([EMCC, test_file('hello_world.c'), '-sINITIAL_MEMORY=33554433']) # 32MB + 1 byte
81878213
self.assertContained('INITIAL_MEMORY must be a multiple of WebAssembly page size (64KiB)', ret)
81888214

@@ -8634,7 +8660,7 @@ def run(args, expected):
86348660
result = self.run_js('a.out.js').strip()
86358661
self.assertEqual(result, f'{expected}, errno: 0')
86368662

8637-
run([], 256)
8663+
run([], 258)
86388664
run(['-sINITIAL_MEMORY=32MB'], 512)
86398665
run(['-sINITIAL_MEMORY=32MB', '-sALLOW_MEMORY_GROWTH'], (2 * 1024 * 1024 * 1024) // webassembly.WASM_PAGE_SIZE)
86408666
run(['-sINITIAL_MEMORY=32MB', '-sALLOW_MEMORY_GROWTH', '-sWASM=0'], (2 * 1024 * 1024 * 1024) // webassembly.WASM_PAGE_SIZE)

tools/building.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,17 @@ def lld_flags_for_executable(external_symbols):
220220
cmd.append('--growable-table')
221221

222222
if not settings.SIDE_MODULE:
223-
# Export these two section start symbols so that we can extract the string
224-
# data that they contain.
225-
cmd += [
226-
'-z', 'stack-size=%s' % settings.STACK_SIZE,
227-
'--initial-memory=%d' % settings.INITIAL_MEMORY,
228-
'--max-memory=%d' % settings.MAXIMUM_MEMORY,
229-
]
223+
cmd += ['-z', 'stack-size=%s' % settings.STACK_SIZE]
224+
225+
if settings.ALLOW_MEMORY_GROWTH:
226+
cmd += ['--max-memory=%d' % settings.MAXIMUM_MEMORY]
227+
else:
228+
cmd += ['--no-growable-memory']
229+
230+
if settings.INITIAL_HEAP != -1:
231+
cmd += ['--initial-heap=%d' % settings.INITIAL_HEAP]
232+
if settings.INITIAL_MEMORY != -1:
233+
cmd += ['--initial-memory=%d' % settings.INITIAL_MEMORY]
230234

231235
if settings.STANDALONE_WASM:
232236
# when settings.EXPECT_MAIN is set we fall back to wasm-ld default of _start

tools/link.py

Lines changed: 88 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -555,25 +555,92 @@ def include_and_export(name):
555555
settings.EXPORTED_RUNTIME_METHODS += ['ExitStatus']
556556

557557

558+
def set_initial_memory():
559+
user_specified_initial_heap = 'INITIAL_HEAP' in user_settings
560+
561+
# INITIAL_HEAP cannot be used when the memory object is created in JS: we don't know
562+
# the size of static data here and thus the total initial memory size.
563+
if settings.IMPORTED_MEMORY:
564+
if user_specified_initial_heap:
565+
# Some of these could (and should) be implemented.
566+
exit_with_error('INITIAL_HEAP is currently not compatible with IMPORTED_MEMORY (which is enabled indirectly via SHARED_MEMORY, RELOCATABLE, ASYNCIFY_LAZY_LOAD_CODE)')
567+
# The default for imported memory is to fall back to INITIAL_MEMORY.
568+
settings.INITIAL_HEAP = -1
569+
570+
if not user_specified_initial_heap:
571+
# For backwards compatibility, we will only use INITIAL_HEAP by default when the user
572+
# specified neither INITIAL_MEMORY nor MAXIMUM_MEMORY. Both place an upper bounds on
573+
# the overall initial linear memory (stack + static data + heap), and we do not know
574+
# the size of static data at this stage. Setting any non-zero initial heap value in
575+
# this scenario would risk pushing users over the limit they have set.
576+
user_specified_initial = settings.INITIAL_MEMORY != -1
577+
user_specified_maximum = 'MAXIMUM_MEMORY' in user_settings or 'WASM_MEM_MAX' in user_settings or 'BINARYEN_MEM_MAX' in user_settings
578+
if user_specified_initial or user_specified_maximum:
579+
settings.INITIAL_HEAP = -1
580+
581+
# Apply the default if we are going with INITIAL_MEMORY.
582+
if settings.INITIAL_HEAP == -1 and settings.INITIAL_MEMORY == -1:
583+
default_setting('INITIAL_MEMORY', 16 * 1024 * 1024)
584+
585+
def check_memory_setting(setting):
586+
if settings[setting] % webassembly.WASM_PAGE_SIZE != 0:
587+
exit_with_error(f'{setting} must be a multiple of WebAssembly page size (64KiB), was {settings[setting]}')
588+
if settings[setting] >= 2**53:
589+
exit_with_error(f'{setting} must be smaller than 2^53 bytes due to JS Numbers (doubles) being used to hold pointer addresses in JS side')
590+
591+
# Due to the aforementioned lack of knowledge about the static data size, we delegate
592+
# checking the overall consistency of these settings to wasm-ld.
593+
if settings.INITIAL_HEAP != -1:
594+
check_memory_setting('INITIAL_HEAP')
595+
596+
if settings.INITIAL_MEMORY != -1:
597+
check_memory_setting('INITIAL_MEMORY')
598+
if settings.INITIAL_MEMORY < settings.STACK_SIZE:
599+
exit_with_error(f'INITIAL_MEMORY must be larger than STACK_SIZE, was {settings.INITIAL_MEMORY} (STACK_SIZE={settings.STACK_SIZE})')
600+
601+
check_memory_setting('MAXIMUM_MEMORY')
602+
if settings.MEMORY_GROWTH_LINEAR_STEP != -1:
603+
check_memory_setting('MEMORY_GROWTH_LINEAR_STEP')
604+
605+
606+
# Set an upper estimate of what MAXIMUM_MEMORY should be. Take note that this value
607+
# may not be precise, and is only an upper bound of the exact value calculated later
608+
# by the linker.
558609
def set_max_memory():
559-
# When memory growth is disallowed set MAXIMUM_MEMORY equal to INITIAL_MEMORY
610+
# With INITIAL_HEAP, we only know the lower bound on initial memory size.
611+
initial_memory_known = settings.INITIAL_MEMORY != -1
612+
560613
if not settings.ALLOW_MEMORY_GROWTH:
561614
if 'MAXIMUM_MEMORY' in user_settings:
562615
diagnostics.warning('unused-command-line-argument', 'MAXIMUM_MEMORY is only meaningful with ALLOW_MEMORY_GROWTH')
563-
settings.MAXIMUM_MEMORY = settings.INITIAL_MEMORY
616+
# Optimization: lower the default maximum memory to initial memory if possible.
617+
if initial_memory_known:
618+
settings.MAXIMUM_MEMORY = settings.INITIAL_MEMORY
564619

620+
# Automaticaly up the default maximum when the user requested a large minimum.
565621
if 'MAXIMUM_MEMORY' not in user_settings:
566-
if settings.ALLOW_MEMORY_GROWTH and settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024:
622+
if settings.ALLOW_MEMORY_GROWTH:
623+
if any([settings.INITIAL_HEAP != -1 and settings.INITIAL_HEAP >= 2 * 1024 * 1024 * 1024,
624+
initial_memory_known and settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024]):
567625
settings.MAXIMUM_MEMORY = 4 * 1024 * 1024 * 1024
568626

569627
# INITIAL_MEMORY sets a lower bound for MAXIMUM_MEMORY
570-
if settings.INITIAL_MEMORY > settings.MAXIMUM_MEMORY:
628+
if initial_memory_known and settings.INITIAL_MEMORY > settings.MAXIMUM_MEMORY:
571629
settings.MAXIMUM_MEMORY = settings.INITIAL_MEMORY
572630

573-
if settings.MAXIMUM_MEMORY < settings.INITIAL_MEMORY:
631+
# A similar check for INITIAL_HEAP would not be precise and so is delegated to wasm-ld.
632+
if initial_memory_known and settings.MAXIMUM_MEMORY < settings.INITIAL_MEMORY:
574633
exit_with_error('MAXIMUM_MEMORY cannot be less than INITIAL_MEMORY')
575634

576635

636+
def inc_initial_memory(delta):
637+
# Both INITIAL_HEAP and INITIAL_MEMORY can be set at the same time. Increment both.
638+
if settings.INITIAL_HEAP != -1:
639+
settings.INITIAL_HEAP += delta
640+
if settings.INITIAL_MEMORY != -1:
641+
settings.INITIAL_MEMORY += delta
642+
643+
577644
def check_browser_versions():
578645
# Map of setting all VM version settings to the minimum version
579646
# we support.
@@ -1362,18 +1429,10 @@ def phase_linker_setup(options, state, newargs):
13621429
'removeRunDependency',
13631430
]
13641431

1365-
def check_memory_setting(setting):
1366-
if settings[setting] % webassembly.WASM_PAGE_SIZE != 0:
1367-
exit_with_error(f'{setting} must be a multiple of WebAssembly page size (64KiB), was {settings[setting]}')
1368-
if settings[setting] >= 2**53:
1369-
exit_with_error(f'{setting} must be smaller than 2^53 bytes due to JS Numbers (doubles) being used to hold pointer addresses in JS side')
1432+
if settings.SHARED_MEMORY or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE:
1433+
settings.IMPORTED_MEMORY = 1
13701434

1371-
check_memory_setting('INITIAL_MEMORY')
1372-
check_memory_setting('MAXIMUM_MEMORY')
1373-
if settings.INITIAL_MEMORY < settings.STACK_SIZE:
1374-
exit_with_error(f'INITIAL_MEMORY must be larger than STACK_SIZE, was {settings.INITIAL_MEMORY} (STACK_SIZE={settings.STACK_SIZE})')
1375-
if settings.MEMORY_GROWTH_LINEAR_STEP != -1:
1376-
check_memory_setting('MEMORY_GROWTH_LINEAR_STEP')
1435+
set_initial_memory()
13771436

13781437
if settings.EXPORT_ES6:
13791438
if not settings.MODULARIZE:
@@ -1433,9 +1492,6 @@ def check_memory_setting(setting):
14331492
(options.shell_path == DEFAULT_SHELL_HTML or options.shell_path == utils.path_from_root('src/shell_minimal.html')):
14341493
exit_with_error(f'Due to collision in variable name "Module", the shell file "{options.shell_path}" is not compatible with build options "-sMODULARIZE -sEXPORT_NAME=Module". Either provide your own shell file, change the name of the export to something else to avoid the name collision. (see https://github.com/emscripten-core/emscripten/issues/7950 for details)')
14351494

1436-
if settings.SHARED_MEMORY or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE:
1437-
settings.IMPORTED_MEMORY = 1
1438-
14391495
if settings.WASM_BIGINT:
14401496
settings.LEGALIZE_JS_FFI = 0
14411497

@@ -1496,9 +1552,9 @@ def check_memory_setting(setting):
14961552
# These values are designed be an over-estimate of the actual requirements and
14971553
# are based on experimentation with different tests/programs under asan and
14981554
# lsan.
1499-
settings.INITIAL_MEMORY += 50 * 1024 * 1024
1555+
inc_initial_memory(50 * 1024 * 1024)
15001556
if settings.PTHREADS:
1501-
settings.INITIAL_MEMORY += 50 * 1024 * 1024
1557+
inc_initial_memory(50 * 1024 * 1024)
15021558

15031559
if settings.USE_OFFSET_CONVERTER:
15041560
if settings.WASM2JS:
@@ -1541,22 +1597,23 @@ def check_memory_setting(setting):
15411597
if 'GLOBAL_BASE' in user_settings:
15421598
exit_with_error("ASan does not support custom GLOBAL_BASE")
15431599

1544-
# Increase the TOTAL_MEMORY and shift GLOBAL_BASE to account for
1600+
# Increase the INITIAL_MEMORY and shift GLOBAL_BASE to account for
15451601
# the ASan shadow region which starts at address zero.
15461602
# The shadow region is 1/8th the size of the total memory and is
15471603
# itself part of the total memory.
15481604
# We use the following variables in this calculation:
15491605
# - user_mem : memory usable/visible by the user program.
15501606
# - shadow_size : memory used by asan for shadow memory.
15511607
# - total_mem : the sum of the above. this is the size of the wasm memory (and must be aligned to WASM_PAGE_SIZE)
1552-
user_mem = settings.INITIAL_MEMORY
1553-
if settings.ALLOW_MEMORY_GROWTH:
1554-
user_mem = settings.MAXIMUM_MEMORY
1608+
user_mem = settings.MAXIMUM_MEMORY
1609+
if not settings.ALLOW_MEMORY_GROWTH and settings.INITIAL_MEMORY != -1:
1610+
user_mem = settings.INITIAL_MEMORY
15551611

15561612
# Given the know value of user memory size we can work backwards
15571613
# to find the total memory and the shadow size based on the fact
15581614
# that the user memory is 7/8ths of the total memory.
15591615
# (i.e. user_mem == total_mem * 7 / 8
1616+
# TODO-Bug?: this does not look to handle 4GB MAXIMUM_MEMORY correctly.
15601617
total_mem = user_mem * 8 / 7
15611618

15621619
# But we might need to re-align to wasm page size
@@ -1569,10 +1626,12 @@ def check_memory_setting(setting):
15691626
# We don't need to worry about alignment here. wasm-ld will take care of that.
15701627
settings.GLOBAL_BASE = shadow_size
15711628

1572-
if not settings.ALLOW_MEMORY_GROWTH:
1573-
settings.INITIAL_MEMORY = total_mem
1574-
else:
1575-
settings.INITIAL_MEMORY += align_to_wasm_page_boundary(shadow_size)
1629+
# Adjust INITIAL_MEMORY (if needed) to account for the shifted global base.
1630+
if settings.INITIAL_MEMORY != -1:
1631+
if settings.ALLOW_MEMORY_GROWTH:
1632+
settings.INITIAL_MEMORY += align_to_wasm_page_boundary(shadow_size)
1633+
else:
1634+
settings.INITIAL_MEMORY = total_mem
15761635

15771636
if settings.SAFE_HEAP:
15781637
# SAFE_HEAP instruments ASan's shadow memory accesses.

0 commit comments

Comments
 (0)