Skip to content

Commit

Permalink
Auto merge of rust-lang#55518 - alexcrichton:smaller-wasm, r=sfackler
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Nov 6, 2018
2 parents 8aa9267 + 0c3d08e commit 24e66c2
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ mod platform {

#[cfg(not(target_feature = "atomics"))]
mod lock {
#[inline]
pub fn lock() {} // no atomics, no threads, that's easy!
}
}
11 changes: 10 additions & 1 deletion src/libstd/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use cell::UnsafeCell;
use fmt;
use hint;
use mem;

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

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

/// Acquires a reference to the value in this TLS key.
Expand Down
3 changes: 3 additions & 0 deletions src/test/run-make/wasm-panic-small/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ all:
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg c
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg d
wc -c < $(TMPDIR)/foo.wasm
[ "`wc -c < $(TMPDIR)/foo.wasm`" -lt "5120" ]
else
all:
endif
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-make/wasm-panic-small/foo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ pub fn foo() {
pub fn foo() {
panic!("{}", "a");
}

#[no_mangle]
#[cfg(d)]
pub fn foo() -> usize {
use std::cell::Cell;
thread_local!(static A: Cell<Vec<u32>> = Cell::new(Vec::new()));
A.try_with(|x| x.replace(Vec::new()).len()).unwrap_or(0)
}

0 comments on commit 24e66c2

Please sign in to comment.