]> git.lizzy.rs Git - rust.git/commitdiff
std: Improve codegen size of accessing TLS
authorAlex Crichton <alex@alexcrichton.com>
Sun, 28 Oct 2018 15:26:47 +0000 (08:26 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 1 Nov 2018 17:46:31 +0000 (10:46 -0700)
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.

src/libstd/thread/local.rs
src/test/run-make/wasm-panic-small/Makefile
src/test/run-make/wasm-panic-small/foo.rs

index 59f100fad1bb9a1eda0aa41d72fa42c6b7c506d6..ccbead7cc2f77f3d77d52ba20bb16e6b11feac72 100644 (file)
@@ -14,6 +14,7 @@
 
 use cell::UnsafeCell;
 use fmt;
+use hint;
 use mem;
 
 /// A thread local storage key which owns its contents.
@@ -275,7 +276,15 @@ unsafe fn init(&self, slot: &UnsafeCell<Option<T>>) -> &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.
index 330ae300c445ee4334e67ed60e88ad53fe383243..48b530c9957254528422e007a40075a1954d4f1d 100644 (file)
@@ -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
index 1ea724ca94d477951407704d3b4ae957d43d0429..441e92976a39671283c142f531172d8cf49504f1 100644 (file)
@@ -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)
+}