Skip to content

Commit 8a18176

Browse files
authored
Rollup merge of #147225 - daxpedda:wasm-u-u-atomics-threads, r=alexcrichton
Don't enable shared memory by default with Wasm atomics This prepares us for a future where LLVM eventually stabilizes the atomics target feature, in which case we don't want to inflate atomics with threads. Otherwise users would be stuck with shared memory even when they don't want it/need it. ### Context Currently the atomics target features is unstable and can't be used without re-building Std with it (`-Zbuild-std`). Enabling the atomics target feature automatically enables shared memory. Shared memory is required to actually allow multi-threading. However, shared memory comes with a performance overhead when atomic instructions aren't able to be lowered to regular memory access instructions or when interacting with certain Web APIs. So it is very undesirable to enable shared memory by default for the majority of users. While it is possible to use atomics without shared memory, the question remains what use-case this scenario has. The only one I can think of would involve multiple memories, where the main memory remains un-shared but a second shared memory exists. While Rust doesn't support multiple memories, it might be possible with inline assembly (#136382). So alternatively, we might consider *not* enabling atomics by default even when LLVM does. In which case everything would remain the same. --- This will break current Web multi-threading users. To address this they can add the following `RUSTFLAGS`: ``` -Clink-args=--shared-memory,--max-memory=1073741824,--import-memory,--export=__wasm_init_tls,--export=__tls_size,--export=__tls_align,--export=__tls_base ``` We could add a new experimental flag that enables the right linker arguments for users, but I feel that's not in Rusts scope. Or like suggested before: a Rust-only `threads` target feature. Addresses #77839. r? ``@alexcrichton``
2 parents b78b107 + 3e8ce2b commit 8a18176

File tree

3 files changed

+13
-36
lines changed

3 files changed

+13
-36
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use rustc_middle::middle::exported_symbols::{
1717
use rustc_middle::ty::TyCtxt;
1818
use rustc_session::Session;
1919
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
20-
use rustc_span::sym;
2120
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};
2221
use tracing::{debug, warn};
2322

@@ -1324,37 +1323,7 @@ struct WasmLd<'a> {
13241323

13251324
impl<'a> WasmLd<'a> {
13261325
fn new(cmd: Command, sess: &'a Session) -> WasmLd<'a> {
1327-
// If the atomics feature is enabled for wasm then we need a whole bunch
1328-
// of flags:
1329-
//
1330-
// * `--shared-memory` - the link won't even succeed without this, flags
1331-
// the one linear memory as `shared`
1332-
//
1333-
// * `--max-memory=1G` - when specifying a shared memory this must also
1334-
// be specified. We conservatively choose 1GB but users should be able
1335-
// to override this with `-C link-arg`.
1336-
//
1337-
// * `--import-memory` - it doesn't make much sense for memory to be
1338-
// exported in a threaded module because typically you're
1339-
// sharing memory and instantiating the module multiple times. As a
1340-
// result if it were exported then we'd just have no sharing.
1341-
//
1342-
// On wasm32-unknown-unknown, we also export symbols for glue code to use:
1343-
// * `--export=*tls*` - when `#[thread_local]` symbols are used these
1344-
// symbols are how the TLS segments are initialized and configured.
1345-
let mut wasm_ld = WasmLd { cmd, sess };
1346-
if sess.target_features.contains(&sym::atomics) {
1347-
wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]);
1348-
if sess.target.os == "unknown" || sess.target.os == "none" {
1349-
wasm_ld.link_args(&[
1350-
"--export=__wasm_init_tls",
1351-
"--export=__tls_size",
1352-
"--export=__tls_align",
1353-
"--export=__tls_base",
1354-
]);
1355-
}
1356-
}
1357-
wasm_ld
1326+
WasmLd { cmd, sess }
13581327
}
13591328
}
13601329

compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base};
66
pub(crate) fn target() -> Target {
77
let mut options = base::linux_wasm::opts();
88

9-
options
10-
.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &["--export-memory", "--shared-memory"]);
9+
options.add_pre_link_args(
10+
LinkerFlavor::WasmLld(Cc::No),
11+
&["--export-memory", "--shared-memory", "--max-memory=1073741824"],
12+
);
1113
options.add_pre_link_args(
1214
LinkerFlavor::WasmLld(Cc::Yes),
13-
&["--target=wasm32-wasi-threads", "-Wl,--export-memory,", "-Wl,--shared-memory"],
15+
&[
16+
"--target=wasm32-wasi-threads",
17+
"-Wl,--export-memory,",
18+
"-Wl,--shared-memory",
19+
"-Wl,--max-memory=1073741824",
20+
],
1421
);
1522

1623
Target {

compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
1919

2020
options.add_pre_link_args(
2121
LinkerFlavor::WasmLld(Cc::No),
22-
&["--import-memory", "--export-memory", "--shared-memory"],
22+
&["--import-memory", "--export-memory", "--shared-memory", "--max-memory=1073741824"],
2323
);
2424
options.add_pre_link_args(
2525
LinkerFlavor::WasmLld(Cc::Yes),
@@ -28,6 +28,7 @@ pub(crate) fn target() -> Target {
2828
"-Wl,--import-memory",
2929
"-Wl,--export-memory,",
3030
"-Wl,--shared-memory",
31+
"-Wl,--max-memory=1073741824",
3132
],
3233
);
3334

0 commit comments

Comments
 (0)