-
Notifications
You must be signed in to change notification settings - Fork 694
Description
Implementation of global variables for LLVM, and subsequent discussion with @ncbray led me to realize an interesting interaction with atomics which I think is worth pointing out and documenting as a "question".
Treat this a a brain dump. In particular, it doesn't require your attention now. Add to it if you wish, let's make sure we close it out before MVP, but let's keep focused on getting some basics working first.
Once we add threading to WebAssembly, are globals accessible atomically?
The answer to this may mean we diverge slightly from JavaScript Shared Memory that @lars-t-hansen is working on. This means that any theorem prover we use to validate the JavaScript memory model has to take global variables into account for WebAssembly.
If we follow LLVM's lead and simply tag load
/store
with atomic
(and a memory order e.g. acquire
/release
/seq_cst
) then this extends quite easily to load_global
and store_global
. If we create separate atomic opcodes from load
/store
, then we must also duplicate load_global
/store_global
with atomic siblings.
An interesting point about global variables is that none of them are address-taken. A code generator could decide to emit no global, and always put things in a heap. That opens up developer's code to heap object overflow, whereas globals are always "safe" (bugs in developers' code can't cause their app to get owned through globals being overwritten).
Globals also potentially lead to better optimization by the .wasm
→machine code translator. Doubly so when dealing with atomics because it provides very precise type and pointer escape information.
Global variables can also be exported to shared objects by name.
I'm now wondering: why isn't global
an attribute on load
/store
the same way atomic
could be?
While we're there, why isn't HEAP
a magical exported global, of byte-array type (assuming we allow array global variables, and force them to always be in bounds) which the main module can share with dynamically loaded libraries? This is going back to what Emscripten does, except it has these handy aliases that type-cast the byte array to other types.