Skip to content

Commit 0c3d08e

Browse files
committed
std: Improve codegen size of accessing TLS
Some code in the TLS implementation in libstd stores `Some(val)` into an `&mut Option<T>` (effectively) and then pulls out `&T`, but it currently uses `.unwrap()` which can codegen into a panic even though it can never panic. With sufficient optimizations enabled (like LTO) the compiler can see through this but this commit helps it along in normal mode (`--release` with Cargo by default) to avoid codegen'ing the panic path. This ends up improving the optimized codegen on wasm by ensuring that a call to panic pulling in more file size doesn't stick around.
1 parent 49ec935 commit 0c3d08e

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

src/libstd/thread/local.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
use cell::UnsafeCell;
1616
use fmt;
17+
use hint;
1718
use mem;
1819

1920
/// A thread local storage key which owns its contents.
@@ -275,7 +276,15 @@ impl<T: 'static> LocalKey<T> {
275276
// operations a little differently and make this safe to call.
276277
mem::replace(&mut *ptr, Some(value));
277278

278-
(*ptr).as_ref().unwrap()
279+
// After storing `Some` we want to get a reference to the contents of
280+
// what we just stored. While we could use `unwrap` here and it should
281+
// always work it empirically doesn't seem to always get optimized away,
282+
// which means that using something like `try_with` can pull in
283+
// panicking code and cause a large size bloat.
284+
match *ptr {
285+
Some(ref x) => x,
286+
None => hint::unreachable_unchecked(),
287+
}
279288
}
280289

281290
/// Acquires a reference to the value in this TLS key.

src/test/run-make/wasm-panic-small/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ all:
1111
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg c
1212
wc -c < $(TMPDIR)/foo.wasm
1313
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
14+
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg d
15+
wc -c < $(TMPDIR)/foo.wasm
16+
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
1417
else
1518
all:
1619
endif

src/test/run-make/wasm-panic-small/foo.rs

+8
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ pub fn foo() {
2727
pub fn foo() {
2828
panic!("{}", "a");
2929
}
30+
31+
#[no_mangle]
32+
#[cfg(d)]
33+
pub fn foo() -> usize {
34+
use std::cell::Cell;
35+
thread_local!(static A: Cell<Vec<u32>> = Cell::new(Vec::new()));
36+
A.try_with(|x| x.replace(Vec::new()).len()).unwrap_or(0)
37+
}

0 commit comments

Comments
 (0)