Skip to content

Commit b1acff2

Browse files
authored
Don't include mem init loading code when it is inside the wasm anyhow (emscripten-core#5844)
* don't include mem init loading code when it is inside the wasm anyhow * don't assign null to memoryInitializer later, that is the initial value anyhow * don't put the mem init in the wasm if using pthreads, as we need to handle it more manually (pthreads don't need to initialize memory, just code) * add a test from juj@a9b66de
1 parent e47ac78 commit b1acff2

File tree

6 files changed

+55
-3
lines changed

6 files changed

+55
-3
lines changed

emcc.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,11 @@ def check(input_file):
11761176
if shared.Settings.BINARYEN_PASSES:
11771177
shared.Settings.BINARYEN_PASSES += ','
11781178
shared.Settings.BINARYEN_PASSES += 'safe-heap'
1179+
# we will include the mem init data in the wasm, when we don't need the
1180+
# mem init file to be loadable by itself
1181+
shared.Settings.MEM_INIT_IN_WASM = 'asmjs' not in shared.Settings.BINARYEN_METHOD and \
1182+
'interpret-asm2wasm' not in shared.Settings.BINARYEN_METHOD and \
1183+
not shared.Settings.USE_PTHREADS
11791184

11801185
# wasm outputs are only possible with a side wasm
11811186
if target.endswith(WASM_ENDINGS):
@@ -1709,7 +1714,7 @@ def repl(m):
17091714
if not shared.Settings.BINARYEN or 'asmjs' in shared.Settings.BINARYEN_METHOD or 'interpret-asm2wasm' in shared.Settings.BINARYEN_METHOD:
17101715
return 'memoryInitializer = "%s";' % shared.JS.get_subresource_location(memfile, embed_memfile(options))
17111716
else:
1712-
return 'memoryInitializer = null;'
1717+
return ''
17131718
src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
17141719
open(final + '.mem.js', 'w').write(src)
17151720
final += '.mem.js'
@@ -2299,8 +2304,7 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
22992304
cmd.append(shared.Building.opt_level_to_str(options.opt_level, options.shrink_level))
23002305
# import mem init file if it exists, and if we will not be using asm.js as a binaryen method (as it needs the mem init file, of course)
23012306
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
2302-
ok_binaryen_method = 'asmjs' not in shared.Settings.BINARYEN_METHOD and 'interpret-asm2wasm' not in shared.Settings.BINARYEN_METHOD
2303-
import_mem_init = mem_file_exists and ok_binaryen_method
2307+
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
23042308
if import_mem_init:
23052309
cmd += ['--mem-init=' + memfile]
23062310
if not shared.Settings.RELOCATABLE:

src/postamble.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Module['asm'] = asm;
66
{{{ maybeExport('FS') }}}
77
{{{ maybeExport('GL') }}}
88

9+
#if MEM_INIT_IN_WASM == 0
910
#if MEM_INIT_METHOD == 2
1011
#if USE_PTHREADS
1112
if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) {
@@ -110,6 +111,7 @@ if (memoryInitializer) {
110111
}
111112
}
112113
#endif
114+
#endif // MEM_INIT_IN_WASM == 0
113115

114116
#if CYBERDWARF
115117
Module['cyberdwarf'] = _cyberdwarf_Debugger(cyberDWARFFile);

src/preamble.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,10 +2106,12 @@ function integrateWasmJS() {
21062106
var oldView = new Int8Array(oldBuffer);
21072107
var newView = new Int8Array(newBuffer);
21082108

2109+
#if MEM_INIT_IN_WASM == 0
21092110
// If we have a mem init file, do not trample it
21102111
if (!memoryInitializer) {
21112112
oldView.set(newView.subarray(Module['STATIC_BASE'], Module['STATIC_BASE'] + Module['STATIC_BUMP']), Module['STATIC_BASE']);
21122113
}
2114+
#endif
21132115

21142116
newView.set(oldView);
21152117
updateGlobalBuffer(newBuffer);

src/settings.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,5 +861,7 @@ var WASM_BINARY_FILE = ''; // name of the file containing wasm binary, if releva
861861
var ASMJS_CODE_FILE = ''; // name of the file containing asm.js, if relevant
862862
var SOURCE_MAP_BASE = ''; // Base URL the source mapfile, if relevant
863863

864+
var MEM_INIT_IN_WASM = 0; // for internal use only
865+
864866
var SUPPORT_BASE64_EMBEDDING = 0; // If set to 1, src/base64Utils.js will be included in the bundle.
865867
// This is set internally when needed (SINGLE_FILE)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <assert.h>
2+
#include <pthread.h>
3+
#include <emscripten.h>
4+
5+
int globalData = 1;
6+
7+
void *thread_main(void *arg)
8+
{
9+
EM_ASM(Module.print('hello from pthread 1: ' + $0), globalData);
10+
assert(globalData == 10);
11+
12+
globalData = 20;
13+
EM_ASM(Module.print('hello from pthread 2: ' + $0), globalData);
14+
assert(globalData == 20);
15+
return 0;
16+
}
17+
18+
int main()
19+
{
20+
EM_ASM(Module.print('hello from main 1: ' + $0), globalData);
21+
assert(globalData == 1);
22+
23+
globalData = 10;
24+
EM_ASM(Module.print('hello from main 2: ' + $0), globalData);
25+
assert(globalData == 10);
26+
27+
pthread_t thread;
28+
pthread_create(&thread, NULL, thread_main, NULL);
29+
pthread_join(thread, 0);
30+
31+
EM_ASM(Module.print('hello from main 3: ' + $0), globalData);
32+
assert(globalData == 20);
33+
#ifdef REPORT_RESULT
34+
REPORT_RESULT(globalData);
35+
#endif
36+
}

tests/test_browser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3329,6 +3329,12 @@ def test_pthread_call_async_on_main_thread(self):
33293329
self.btest(path_from_root('tests', 'pthread', 'call_async_on_main_thread.c'), expected='7', args=['-O3', '-s', 'USE_PTHREADS=1', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_async_on_main_thread.js')])
33303330
self.btest(path_from_root('tests', 'pthread', 'call_async_on_main_thread.c'), expected='7', args=['-Oz', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_async_on_main_thread.js')])
33313331

3332+
# Tests that spawning a new thread does not cause a reinitialization of the global data section of the application memory area.
3333+
def test_pthread_global_data_initialization(self):
3334+
for mem_init_mode in [[], ['--memory-init-file', '0'], ['--memory-init-file', '1']]:
3335+
for args in [[], ['-O3']]:
3336+
self.btest(path_from_root('tests', 'pthread', 'test_pthread_global_data_initialization.c'), expected='20', args=args+mem_init_mode+['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1'], also_wasm=False)
3337+
33323338
# test atomicrmw i64
33333339
def test_atomicrmw_i64(self):
33343340
Popen([PYTHON, EMCC, path_from_root('tests', 'atomicrmw_i64.ll'), '-s', 'USE_PTHREADS=1', '-s', 'IN_TEST_HARNESS=1', '-o', 'test.html']).communicate()

0 commit comments

Comments
 (0)