Skip to content

Commit d4cd0c7

Browse files
authored
Simplify GROWABLE_HEAP transform (#24295)
Similar to #24291, but for the transform handling `-pthread` + `-sALLOW_MEMORY_GROWTH`. In the first commit I added a codesize variation to commit current sizes, and in the second you can see that this transform actually saves the total size in addition to making acorn-optimizer simpler.
1 parent 451bbc6 commit d4cd0c7

17 files changed

+333
-197
lines changed

site/source/docs/porting/pthreads.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ The Emscripten implementation for the pthreads API should follow the POSIX stand
144144

145145
- Note that the function emscripten_num_logical_cores() will always return the value of navigator.hardwareConcurrency, i.e. the number of logical cores on the system, even when shared memory is not supported. This means that it is possible for emscripten_num_logical_cores() to return a value greater than 1, while at the same time emscripten_has_threading_support() can return false. The return value of emscripten_has_threading_support() denotes whether the browser has shared memory support available.
146146

147-
- Pthreads + memory growth (``ALLOW_MEMORY_GROWTH``) is especially tricky, see `Wasm design issue #1271 <https://github.com/WebAssembly/design/issues/1271>`_. This currently causes JS accessing the Wasm memory to be slow - but this will likely only be noticeable if the JS does large amounts of memory reads and writes (Wasm runs at full speed, so moving work over can fix this). This also requires that your JS be aware that the HEAP* views may need to be updated - JS code embedded with ``--js-library`` etc will automatically be transformed to use the ``GROWABLE_HEAP_*`` helper functions where ``HEAP*`` are used, but external code that uses ``Module.HEAP*`` directly may encounter problems with views being smaller than memory.
147+
- Pthreads + memory growth (``ALLOW_MEMORY_GROWTH``) is especially tricky, see `Wasm design issue #1271 <https://github.com/WebAssembly/design/issues/1271>`_. This currently causes JS accessing the Wasm memory to be slow - but this will likely only be noticeable if the JS does large amounts of memory reads and writes (Wasm runs at full speed, so moving work over can fix this). This also requires that your JS be aware that the HEAP* views may need to be updated - JS code embedded with ``--js-library`` etc will automatically be transformed to auto-update memory views before each access, but external code that uses ``Module.HEAP*`` directly may encounter problems with views being smaller than memory.
148148

149149
.. _Allocator_performance:
150150

src/growableHeap.js

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,63 +6,9 @@
66

77
// Support for growable heap + pthreads, where the buffer may change, so JS views
88
// must be updated.
9-
function GROWABLE_HEAP_I8() {
9+
function growMemViews() {
10+
// `updateMemoryViews` updates all the views simultaneously, so it's enough to check any of them.
1011
if (wasmMemory.buffer != HEAP8.buffer) {
1112
updateMemoryViews();
1213
}
13-
return HEAP8;
14-
}
15-
function GROWABLE_HEAP_U8() {
16-
if (wasmMemory.buffer != HEAP8.buffer) {
17-
updateMemoryViews();
18-
}
19-
return HEAPU8;
20-
}
21-
function GROWABLE_HEAP_I16() {
22-
if (wasmMemory.buffer != HEAP8.buffer) {
23-
updateMemoryViews();
24-
}
25-
return HEAP16;
26-
}
27-
function GROWABLE_HEAP_U16() {
28-
if (wasmMemory.buffer != HEAP8.buffer) {
29-
updateMemoryViews();
30-
}
31-
return HEAPU16;
32-
}
33-
function GROWABLE_HEAP_I32() {
34-
if (wasmMemory.buffer != HEAP8.buffer) {
35-
updateMemoryViews();
36-
}
37-
return HEAP32;
38-
}
39-
function GROWABLE_HEAP_U32() {
40-
if (wasmMemory.buffer != HEAP8.buffer) {
41-
updateMemoryViews();
42-
}
43-
return HEAPU32;
44-
}
45-
function GROWABLE_HEAP_I64() {
46-
if (wasmMemory.buffer != HEAP8.buffer) {
47-
updateMemoryViews();
48-
}
49-
return HEAP64;
50-
}
51-
function GROWABLE_HEAP_U64() {
52-
if (wasmMemory.buffer != HEAP8.buffer) {
53-
updateMemoryViews();
54-
}
55-
return HEAPU64;
56-
}
57-
function GROWABLE_HEAP_F32() {
58-
if (wasmMemory.buffer != HEAP8.buffer) {
59-
updateMemoryViews();
60-
}
61-
return HEAPF32;
62-
}
63-
function GROWABLE_HEAP_F64() {
64-
if (wasmMemory.buffer != HEAP8.buffer) {
65-
updateMemoryViews();
66-
}
67-
return HEAPF64;
6814
}

src/lib/libpthread.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -979,11 +979,6 @@ var LibraryPThread = {
979979
$establishStackSpace__internal: true,
980980
$establishStackSpace__deps: ['$stackRestore', 'emscripten_stack_set_limits'],
981981
$establishStackSpace: (pthread_ptr) => {
982-
#if ALLOW_MEMORY_GROWTH
983-
// If memory growth is enabled, the memory views may have gotten out of date,
984-
// so resync them before accessing the pthread ptr below.
985-
updateMemoryViews();
986-
#endif
987982
var stackHigh = {{{ makeGetValue('pthread_ptr', C_STRUCTS.pthread.stack, '*') }}};
988983
var stackSize = {{{ makeGetValue('pthread_ptr', C_STRUCTS.pthread.stack_size, '*') }}};
989984
var stackLow = stackHigh - stackSize;

src/modules.mjs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -455,20 +455,6 @@ function exportRuntimeSymbols() {
455455
runtimeElements.push('HEAP_DATA_VIEW');
456456
}
457457

458-
if (PTHREADS && ALLOW_MEMORY_GROWTH) {
459-
runtimeElements.push(
460-
'GROWABLE_HEAP_I8',
461-
'GROWABLE_HEAP_U8',
462-
'GROWABLE_HEAP_I16',
463-
'GROWABLE_HEAP_U16',
464-
'GROWABLE_HEAP_I32',
465-
'GROWABLE_HEAP_U32',
466-
'GROWABLE_HEAP_I64',
467-
'GROWABLE_HEAP_U64',
468-
'GROWABLE_HEAP_F32',
469-
'GROWABLE_HEAP_F64',
470-
);
471-
}
472458
if (USE_OFFSET_CONVERTER) {
473459
runtimeElements.push('WasmOffsetConverter');
474460
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
function f() {
22
var $2 = 0;
3-
GROWABLE_HEAP_I32()[$0 >> 2] = $2 + 1;
4-
$9 = GROWABLE_HEAP_U8()[$2 >> 0] | 0;
5-
+GROWABLE_HEAP_F64()[x >> 3];
6-
GROWABLE_HEAP_I64()[x >> 3] = GROWABLE_HEAP_I64()[y >> 3];
3+
(growMemViews(), HEAP32)[$0 >> 2] = $2 + 1;
4+
$9 = (growMemViews(), HEAPU8)[$2 >> 0] | 0;
5+
+(growMemViews(), HEAPF64)[x >> 3];
6+
(growMemViews(), HEAP64)[x >> 3] = (growMemViews(), HEAP64)[y >> 3];
77
}
88

99
function libraryFunc(ptr, val) {
10-
if (ptr < GROWABLE_HEAP_I8().length) {
11-
Atomics.wait(GROWABLE_HEAP_I32(), ptr, val);
10+
if (ptr < (growMemViews(), HEAP8).length) {
11+
Atomics.wait((growMemViews(), HEAP32), ptr, val);
1212
}
1313
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
A (_emscripten_thread_exit)
2+
B (_emscripten_check_mailbox)
3+
C (emscripten_stack_set_limits)
4+
D (_emscripten_stack_restore)
5+
E (_emscripten_stack_alloc)
6+
F (emscripten_stack_get_current)
7+
p (__wasm_call_ctors)
8+
q (add)
9+
r (main)
10+
s (__indirect_function_table)
11+
t (_emscripten_tls_init)
12+
u (pthread_self)
13+
v (_emscripten_proxy_main)
14+
w (_emscripten_thread_init)
15+
x (_emscripten_thread_crashed)
16+
y (_emscripten_run_on_main_thread_js)
17+
z (_emscripten_thread_free_data)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
$__emscripten_stdout_seek
2+
$__errno_location
3+
$__memcpy
4+
$__memset
5+
$__pthread_getspecific
6+
$__pthread_mutex_lock
7+
$__pthread_mutex_trylock
8+
$__pthread_mutex_unlock
9+
$__pthread_rwlock_timedrdlock
10+
$__pthread_rwlock_tryrdlock
11+
$__pthread_rwlock_trywrlock
12+
$__pthread_rwlock_unlock
13+
$__pthread_self_internal
14+
$__pthread_setcancelstate
15+
$__set_thread_state
16+
$__stdio_write
17+
$__timedwait
18+
$__timedwait_cp
19+
$__tl_lock
20+
$__tl_unlock
21+
$__wait
22+
$__wake
23+
$__wake
24+
$__wasi_syscall_ret
25+
$__wasm_call_ctors
26+
$__wasm_init_memory
27+
$__wasm_init_tls
28+
$_emscripten_check_mailbox
29+
$_emscripten_proxy_main
30+
$_emscripten_run_on_main_thread_js
31+
$_emscripten_stack_alloc
32+
$_emscripten_stack_restore
33+
$_emscripten_thread_crashed
34+
$_emscripten_thread_exit
35+
$_emscripten_thread_free_data
36+
$_emscripten_thread_init
37+
$_emscripten_thread_mailbox_init
38+
$_emscripten_tls_init
39+
$_emscripten_yield
40+
$_main_thread
41+
$a_cas
42+
$a_cas
43+
$a_cas_p
44+
$a_dec
45+
$a_fetch_add
46+
$a_fetch_add
47+
$a_inc
48+
$a_store
49+
$a_swap
50+
$add
51+
$call_callback_then_free_ctx
52+
$call_cancel_then_free_ctx
53+
$call_then_finish_task
54+
$call_with_ctx
55+
$cancel_active_ctxs
56+
$cancel_ctx
57+
$cancel_notification
58+
$dispose_chunk
59+
$do_proxy
60+
$em_proxying_ctx_deinit
61+
$em_task_queue_cancel
62+
$em_task_queue_create
63+
$em_task_queue_dequeue
64+
$em_task_queue_enqueue
65+
$em_task_queue_execute
66+
$em_task_queue_free
67+
$em_task_queue_is_empty
68+
$emscripten_builtin_free
69+
$emscripten_builtin_malloc
70+
$emscripten_futex_wait
71+
$emscripten_futex_wake
72+
$emscripten_stack_get_current
73+
$emscripten_stack_set_limits
74+
$free_ctx
75+
$get_tasks_for_thread
76+
$init_active_ctxs
77+
$init_file_lock
78+
$init_mparams
79+
$lock
80+
$main
81+
$nodtor
82+
$pthread_attr_destroy
83+
$pthread_cond_signal
84+
$pthread_mutex_destroy
85+
$pthread_setspecific
86+
$receive_notification
87+
$remove_active_ctx
88+
$run_js_func
89+
$sbrk
90+
$undo
91+
$unlock
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3991
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
a (memory)
2+
b (emscripten_get_now)
3+
c (exit)
4+
d (_emscripten_thread_set_strongref)
5+
e (fd_write)
6+
f (emscripten_runtime_keepalive_check)
7+
g (emscripten_resize_heap)
8+
h (emscripten_exit_with_live_runtime)
9+
i (emscripten_check_blocking_allowed)
10+
j (_emscripten_thread_mailbox_await)
11+
k (_emscripten_thread_cleanup)
12+
l (_emscripten_receive_on_main_thread_js)
13+
m (_emscripten_notify_mailbox_postmessage)
14+
n (_emscripten_init_main_thread_js)
15+
o (__pthread_create_js)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
8263

0 commit comments

Comments
 (0)