forked from OSchip/llvm-project
![]() For multithreaded modules (i.e. modules with a shared memory), lld injects a synthetic Wasm start function that is automatically called during instantiation to initialize memory from passive data segments. Even though the module will be instantiated separately on each thread, memory initialization should happen only once. Furthermore, memory initialization should be finished by the time each thread finishes instantiation. Since multiple threads may be instantiating their modules at the same time, the synthetic function must synchronize them. The current synchronization tries to atomically increment a flag from 0 to 1 in memory then enters one of two cases. First, if the increment was successful, the current thread is responsible for initializing memory. It does so, increments the flag to 2 to signify that memory has been initialized, then notifies all threads waiting on the flag. Otherwise, the thread atomically waits on the flag with an expected value of 1 until memory has been initialized. Either the initializer thread finishes initializing memory (i.e. sets the flag to 2) first and the waiter threads do not end up blocking, or the waiter threads succesfully start waiting before memory is initialized so they will be woken by the initializer thread once it has finished. One complication with this scheme is that there are various contexts on the Web, most notably on the main browser thread, that cannot successfully execute a wait. Executing a wait in these contexts causes a trap, and in this case would cause instantiation to fail. The embedder must therefore ensure that these contexts win the race and become responsible for initializing memory, since that is the only code path that does not execute a wait. Unfortunately, since only one thread can win the race and initialize memory, this scheme makes it impossible to have multiple threads in contexts that cannot wait. For example, it is not currently possible to instantiate the module on both the main browser thread as well as in an AudioWorklet. To loosen this restriction, this commit inserts an extra check so that the wait will not be executed at all when memory has already been initialized, i.e. when the flag value is 2. After this change, the module can be instantiated on threads in non-waiting contexts as long as the embedder can guarantee either that the thread will win the race and initialize memory (as before) or that memory has already been initialized when instantiation begins. Threads in contexts that can wait can continue racing to initialize memory. Fixes (or at least improves) PR51702. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D109722 |
||
---|---|---|
.. | ||
COFF | ||
Common | ||
ELF | ||
MachO | ||
MinGW | ||
cmake/modules | ||
docs | ||
include/lld | ||
lib | ||
test | ||
tools/lld | ||
unittests | ||
utils | ||
wasm | ||
.clang-format | ||
.clang-tidy | ||
.gitignore | ||
CMakeLists.txt | ||
CODE_OWNERS.TXT | ||
LICENSE.TXT | ||
README.md |
README.md
LLVM Linker (lld)
This directory and its subdirectories contain source code for the LLVM Linker, a modular cross platform linker which is built as part of the LLVM compiler infrastructure project.
lld is open source software. You may freely distribute it under the terms of the license agreement found in LICENSE.txt.
Benchmarking
In order to make sure various developers can evaluate patches over the same tests, we create a collection of self contained programs.
It is hosted at https://s3-us-west-2.amazonaws.com/linker-tests/lld-speed-test.tar.xz
The current sha256 is 10eec685463d5a8bbf08d77f4ca96282161d396c65bd97dc99dbde644a31610f
.