Skip to content

Commit d68a593

Browse files
committed
[wasm2js] Remove all handling for external memory file
We have a lot of support code and complexity in emscripten for handling of external memory files. However, its only ever used in wasm2js mode which is a legacy mode. The only reason we continue to support it here IIUC is because its slightly more space efficient than embedding the data as base64. For small programs like hello_world this is an over codesize win. For larger programs there is a regression in overall size in proportion to the amount of static data in the program.
1 parent a3b9509 commit d68a593

22 files changed

+119
-535
lines changed

ChangeLog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ See docs/process.md for more on how version tagging works.
2121
3.1.55 (in development)
2222
-----------------------
2323
- Update sdl2-mixer port from 2.6.0 to 2.8.0
24+
- Emscripten no longer supports `--memory-init-file` (i.e. extracting static
25+
data into an external .mem file). This feature was only available under
26+
wasm2js (`-sWASM=0`) anyway so this change will only effect users of this
27+
setting.
2428

2529
3.1.54 - 02/15/24
2630
-----------------
@@ -58,7 +62,6 @@ See docs/process.md for more on how version tagging works.
5862
- Allow comments in response files. Any line starting with `#` is now ignored.
5963
This is useful when listing exported symbols. (#21330)
6064

61-
6265
3.1.53 - 01/29/24
6366
-----------------
6467
- The llvm version that emscripten uses was updated to 19.0.0 trunk. (#21165)

docs/emcc.txt

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -493,49 +493,6 @@ Options that are modified or new in *emcc* are listed below:
493493
Ports repos. After this operation is complete, this process will
494494
exit.
495495

496-
"--memory-init-file 0|1"
497-
[link] Specifies whether to emit a separate memory initialization
498-
file.
499-
500-
Note:
501-
502-
Note that this is only relevant when *not* emitting Wasm, as
503-
Wasm embeds the memory init data in the Wasm binary.
504-
505-
Possible values are:
506-
507-
* "0": Do not emit a separate memory initialization file.
508-
Instead keep the static initialization inside the generated
509-
JavaScript as text. This is the default setting if compiling
510-
with -O0 or -O1 link-time optimization flags.
511-
512-
* "1": Emit a separate memory initialization file in binary
513-
format. This is more efficient than storing it as text inside
514-
JavaScript, but does mean you have another file to publish.
515-
The binary file will also be loaded asynchronously, which
516-
means "main()" will not be called until the file is downloaded
517-
and applied; you cannot call any C functions until it arrives.
518-
This is the default setting when compiling with -O2 or higher.
519-
520-
Note:
521-
522-
The safest way to ensure that it is safe to call C functions
523-
(the initialisation file has loaded) is to call a notifier
524-
function from "main()".
525-
526-
Note:
527-
528-
If you assign a network request to
529-
"Module.memoryInitializerRequest" (before the script runs),
530-
then it will use that request instead of automatically
531-
starting a download for you. This is beneficial in that you
532-
can, in your HTML, fire off a request for the memory init
533-
file before the script actually arrives. For this to work,
534-
the network request should be an XMLHttpRequest with
535-
responseType set to "'arraybuffer'". (You can also put any
536-
other object here, all it must provide is a ".response"
537-
property containing an ArrayBuffer.)
538-
539496
"-Wwarn-absolute-paths"
540497
[compile+link] Enables warnings about the use of absolute paths in
541498
"-I" and "-L" command line directives. This is used to warn against

emcc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ def __init__(self):
145145
self.emrun = False
146146
self.cpu_profiler = False
147147
self.memory_profiler = False
148-
self.memory_init_file = None
149148
self.use_preload_cache = False
150149
self.use_preload_plugins = False
151150
self.valid_abspaths = []
@@ -1316,7 +1315,7 @@ def consume_arg_file():
13161315
ports.show_ports()
13171316
should_exit = True
13181317
elif check_arg('--memory-init-file'):
1319-
options.memory_init_file = int(consume_arg())
1318+
exit_with_error('--memory-init-file is no longer supported')
13201319
elif check_flag('--proxy-to-worker'):
13211320
settings_changes.append('PROXY_TO_WORKER=1')
13221321
elif check_arg('--valid-abspath'):

site/source/docs/getting_started/FAQ.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,11 @@ function `x` called before runtime initialization``, which is a check enabled in
308308
``ASSERTIONS`` builds.)
309309

310310
Calling a compiled function before a page has fully loaded can result in an
311-
error, if the function relies on files that may not be present (for example the
312-
:ref:`.mem <emcc-memory-init-file>` file and :ref:`preloaded
313-
<emcc-preload-file>` files are loaded asynchronously, and therefore if you just
314-
place some JS that calls compiled code in a ``--post-js``, that code will be
315-
called synchronously at the end of the combined JS file, potentially before the
316-
asynchronous event happens, which is bad).
311+
error, if the function relies on files that may not be present (for example
312+
:ref:`preloaded <emcc-preload-file>` files are loaded asynchronously, and
313+
therefore if you just place some JS that calls compiled code in a ``--post-js``,
314+
that code will be called synchronously at the end of the combined JS file,
315+
potentially before the asynchronous event happens, which is bad).
317316

318317
The easiest way to find out when loading is complete is to add a ``main()``
319318
function, and within it call a JavaScript function to notify your code that

site/source/docs/tools_reference/emcc.rst

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -487,24 +487,6 @@ Options that are modified or new in *emcc* are listed below:
487487
[general]
488488
Shows the list of available projects in the Emscripten Ports repos. After this operation is complete, this process will exit.
489489

490-
.. _emcc-memory-init-file:
491-
492-
``--memory-init-file 0|1``
493-
[link]
494-
Specifies whether to emit a separate memory initialization file.
495-
496-
.. note:: Note that this is only relevant when *not* emitting Wasm, as Wasm embeds the memory init data in the Wasm binary.
497-
498-
Possible values are:
499-
500-
- ``0``: Do not emit a separate memory initialization file. Instead keep the static initialization inside the generated JavaScript as text. This is the default setting if compiling with -O0 or -O1 link-time optimization flags.
501-
- ``1``: Emit a separate memory initialization file in binary format. This is more efficient than storing it as text inside JavaScript, but does mean you have another file to publish. The binary file will also be loaded asynchronously, which means ``main()`` will not be called until the file is downloaded and applied; you cannot call any C functions until it arrives. This is the default setting when compiling with -O2 or higher.
502-
503-
.. note:: The :ref:`safest way <faq-when-safe-to-call-compiled-functions>` to ensure that it is safe to call C functions (the initialisation file has loaded) is to call a notifier function from ``main()``.
504-
505-
.. note:: If you assign a network request to ``Module.memoryInitializerRequest`` (before the script runs), then it will use that request instead of automatically starting a download for you. This is beneficial in that you can, in your HTML, fire off a request for the memory init file before the script actually arrives. For this to work, the network request should be an XMLHttpRequest with responseType set to ``'arraybuffer'``. (You can also put any other object here, all it must provide is a ``.response`` property containing an ArrayBuffer.)
506-
507-
508490
``-Wwarn-absolute-paths``
509491
[compile+link]
510492
Enables warnings about the use of absolute paths in ``-I`` and ``-L`` command line directives. This is used to warn against unintentional use of absolute paths, which is sometimes dangerous when referring to nonportable local system headers.

src/postamble_minimal.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,6 @@ WebAssembly.instantiate(Module['wasm'], imports).then((output) => {
221221
updateMemoryViews();
222222
#endif
223223

224-
#if !MEM_INIT_IN_WASM && !SINGLE_FILE
225-
#if ASSERTIONS
226-
if (!Module['mem']) throw 'Must load memory initializer as an ArrayBuffer in to variable Module.mem before adding compiled output .js script to the DOM';
227-
#endif
228-
HEAPU8.set(new Uint8Array(Module['mem']), {{{ GLOBAL_BASE }}});
229-
#endif
230-
231224
initRuntime(wasmExports);
232225
#if PTHREADS
233226
// Export Wasm module for pthread creation to access.

src/preamble.js

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -990,9 +990,6 @@ function createWasm() {
990990
#endif
991991
updateMemoryViews();
992992
#endif
993-
#if !MEM_INIT_IN_WASM
994-
runMemoryInitializer();
995-
#endif
996993

997994
#if '$wasmTable' in addedLibraryItems && !RELOCATABLE
998995
wasmTable = wasmExports['__indirect_function_table'];
@@ -1140,88 +1137,6 @@ function getCompilerSetting(name) {
11401137
}
11411138
#endif // RETAIN_COMPILER_SETTINGS
11421139

1143-
#if !MEM_INIT_IN_WASM
1144-
var memoryInitializer = <<< MEM_INITIALIZER >>>;
1145-
1146-
function runMemoryInitializer() {
1147-
#if PTHREADS
1148-
if (ENVIRONMENT_IS_PTHREAD) return;
1149-
#endif
1150-
if (!isDataURI(memoryInitializer)) {
1151-
memoryInitializer = locateFile(memoryInitializer);
1152-
}
1153-
if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
1154-
var data = readBinary(memoryInitializer);
1155-
HEAPU8.set(data, {{{ GLOBAL_BASE }}});
1156-
} else {
1157-
addRunDependency('memory initializer');
1158-
var applyMemoryInitializer = (data) => {
1159-
if (data.byteLength) data = new Uint8Array(data);
1160-
#if ASSERTIONS
1161-
for (var i = 0; i < data.length; i++) {
1162-
assert(HEAPU8[{{{ GLOBAL_BASE }}} + i] === 0, "area for memory initializer should not have been touched before it's loaded");
1163-
}
1164-
#endif
1165-
HEAPU8.set(data, {{{ GLOBAL_BASE }}});
1166-
// Delete the typed array that contains the large blob of the memory initializer request response so that
1167-
// we won't keep unnecessary memory lying around. However, keep the XHR object itself alive so that e.g.
1168-
// its .status field can still be accessed later.
1169-
if (Module['memoryInitializerRequest']) delete Module['memoryInitializerRequest'].response;
1170-
removeRunDependency('memory initializer');
1171-
};
1172-
var doBrowserLoad = () => {
1173-
readAsync(memoryInitializer, applyMemoryInitializer, () => {
1174-
var e = new Error('could not load memory initializer ' + memoryInitializer);
1175-
#if MODULARIZE
1176-
readyPromiseReject(e);
1177-
#else
1178-
throw e;
1179-
#endif
1180-
});
1181-
};
1182-
#if SUPPORT_BASE64_EMBEDDING
1183-
var memoryInitializerBytes = tryParseAsDataURI(memoryInitializer);
1184-
if (memoryInitializerBytes) {
1185-
applyMemoryInitializer(memoryInitializerBytes.buffer);
1186-
} else
1187-
#endif
1188-
if (Module['memoryInitializerRequest']) {
1189-
// a network request has already been created, just use that
1190-
var useRequest = () => {
1191-
var request = Module['memoryInitializerRequest'];
1192-
var response = request.response;
1193-
if (request.status !== 200 && request.status !== 0) {
1194-
#if SUPPORT_BASE64_EMBEDDING
1195-
var data = tryParseAsDataURI(Module['memoryInitializerRequestURL']);
1196-
if (data) {
1197-
response = data.buffer;
1198-
} else {
1199-
#endif
1200-
// If you see this warning, the issue may be that you are using locateFile and defining it in JS. That
1201-
// means that the HTML file doesn't know about it, and when it tries to create the mem init request early, does it to the wrong place.
1202-
// Look in your browser's devtools network console to see what's going on.
1203-
console.warn('a problem seems to have happened with Module.memoryInitializerRequest, status: ' + request.status + ', retrying ' + memoryInitializer);
1204-
doBrowserLoad();
1205-
return;
1206-
#if SUPPORT_BASE64_EMBEDDING
1207-
}
1208-
#endif
1209-
}
1210-
applyMemoryInitializer(response);
1211-
};
1212-
if (Module['memoryInitializerRequest'].response) {
1213-
setTimeout(useRequest, 0); // it's already here; but, apply it asynchronously
1214-
} else {
1215-
Module['memoryInitializerRequest'].addEventListener('load', useRequest); // wait for it
1216-
}
1217-
} else {
1218-
// fetch it from the network ourselves
1219-
doBrowserLoad();
1220-
}
1221-
}
1222-
}
1223-
#endif // MEM_INIT_IN_WASM == 0
1224-
12251140
#if MAIN_MODULE && ASYNCIFY
12261141
// With MAIN_MODULE + ASYNCIFY the normal method of placing stub functions in
12271142
// wasmImports for as-yet-undefined symbols doesn't work since ASYNCIFY then

src/settings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ var INCOMING_MODULE_JS_API = [
959959
'onCustomMessage', 'onExit', 'onFree', 'onFullScreen', 'onMalloc',
960960
'onRealloc', 'onRuntimeInitialized', 'postMainLoop', 'postRun', 'preInit',
961961
'preMainLoop', 'preRun',
962-
'preinitializedWebGLContext', 'memoryInitializerRequest', 'preloadPlugins',
962+
'preinitializedWebGLContext', 'preloadPlugins',
963963
'print', 'printErr', 'quit', 'setStatus', 'statusMessage', 'stderr',
964964
'stdin', 'stdout', 'thisProgram', 'wasm', 'wasmBinary', 'websocket'
965965
];

src/settings_internal.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ var AUDIO_WORKLET_FILE = '';
143143
// Base URL the source mapfile, if relevant
144144
var SOURCE_MAP_BASE = '';
145145

146-
// When this is false we use an external memory init file
147-
// See --memory-init-file. When not using wasm2js this flag is ignored, and
148-
// this setting will always be true.
149-
var MEM_INIT_IN_WASM = true;
150-
151146
// If set to 1, src/base64Utils.js will be included in the bundle.
152147
// This is set internally when needed (SINGLE_FILE)
153148
var SUPPORT_BASE64_EMBEDDING = false;

src/shell.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ if (ENVIRONMENT_IS_NODE) {
439439
// Merge back in the overrides
440440
Object.assign(Module, moduleOverrides);
441441
// Free the object hierarchy contained in the overrides, this lets the GC
442-
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
442+
// reclaim data used.
443443
moduleOverrides = null;
444444
#if ASSERTIONS
445445
checkIncomingModuleAPI();

src/shell_minimal.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ if (ENVIRONMENT_IS_NODE && ENVIRONMENT_IS_SHELL) {
8282
#endif
8383

8484
#if !SINGLE_FILE
85-
#if ENVIRONMENT_MAY_BE_NODE && ((WASM == 1 && (!WASM2JS || !MEM_INIT_IN_WASM)) || WASM == 2)
85+
#if ENVIRONMENT_MAY_BE_NODE && ((WASM == 1 && !WASM2JS) || WASM == 2)
8686
// Wasm or Wasm2JS loading:
8787

8888
if (ENVIRONMENT_IS_NODE) {
@@ -95,13 +95,10 @@ if (ENVIRONMENT_IS_NODE) {
9595
Module['wasm'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm');
9696
#endif
9797
#endif
98-
#if !MEM_INIT_IN_WASM
99-
Module['mem'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.mem');
100-
#endif
10198
}
10299
#endif
103100

104-
#if ENVIRONMENT_MAY_BE_SHELL && ((WASM == 1 && (!WASM2JS || !MEM_INIT_IN_WASM)) || WASM == 2)
101+
#if ENVIRONMENT_MAY_BE_SHELL && ((WASM == 1 && !WASM2JS) || WASM == 2)
105102
if (ENVIRONMENT_IS_SHELL) {
106103
#if WASM == 2
107104
if (typeof WebAssembly != 'undefined') Module['wasm'] = read('{{{ TARGET_BASENAME }}}.wasm', 'binary');
@@ -111,9 +108,6 @@ if (ENVIRONMENT_IS_SHELL) {
111108
Module['wasm'] = read('{{{ TARGET_BASENAME }}}.wasm', 'binary');
112109
#endif
113110
#endif
114-
#if !MEM_INIT_IN_WASM
115-
Module['mem'] = read('{{{ TARGET_BASENAME }}}.mem', 'binary');
116-
#endif
117111
}
118112
#endif
119113

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{
2-
"a.html": 567,
3-
"a.html.gz": 379,
4-
"a.js": 17800,
5-
"a.js.gz": 7981,
6-
"a.mem": 3123,
7-
"a.mem.gz": 2693,
8-
"total": 21490,
9-
"total_gz": 11053
2+
"a.html": 354,
3+
"a.html.gz": 266,
4+
"a.js": 22323,
5+
"a.js.gz": 11632,
6+
"total": 22677,
7+
"total_gz": 11898
108
}
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{
2-
"a.html": 567,
3-
"a.html.gz": 379,
4-
"a.js": 17272,
5-
"a.js.gz": 7814,
6-
"a.mem": 3123,
7-
"a.mem.gz": 2693,
8-
"total": 20962,
9-
"total_gz": 10886
2+
"a.html": 354,
3+
"a.html.gz": 266,
4+
"a.js": 21794,
5+
"a.js.gz": 11450,
6+
"total": 22148,
7+
"total_gz": 11716
108
}

0 commit comments

Comments
 (0)