about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authortyler <tyler@brainiumstudios.com>2019-05-10 17:29:43 -0700
committertyler <tyler@brainiumstudios.com>2019-05-15 07:30:34 -0700
commit1a7f774914d8d3c2a16e40332ad43270c461ec71 (patch)
tree86f7883cd830bc7fc31f10f017c1f9e597419c1c /src/libstd/thread
parent060d8bb6b014f9e9c8b697c5ecd6d86159f122b9 (diff)
downloadrust-1a7f774914d8d3c2a16e40332ad43270c461ec71.tar.gz
rust-1a7f774914d8d3c2a16e40332ad43270c461ec71.zip
- remove unnecessary inlines
- add comment explaining that the fast::Key data structure was carefully constructed for fast access on OSX
- remove inline(never) from the initializer for types where `needs_drop::<T>()` is false
Diffstat (limited to 'src/libstd/thread')
-rw-r--r--src/libstd/thread/local.rs39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index a56a34deba2..e6f096a8da5 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -275,7 +275,6 @@ mod lazy {
             }
         }
 
-        #[inline]
         pub unsafe fn get(&self) -> Option<&'static T> {
             (*self.inner.get()).as_ref()
         }
@@ -346,7 +345,6 @@ pub mod statik {
             }
         }
 
-        #[inline]
         pub unsafe fn get(&self, init: fn() -> T) -> Option<&'static T> {
             let value = match self.inner.get() {
                 Some(ref value) => value,
@@ -373,6 +371,11 @@ pub mod fast {
         RunningOrHasRun,
     }
 
+    // This data structure has been carefully constructed so that the fast path
+    // only contains one branch on x86. That optimization is necessary to avoid
+    // duplicated tls lookups on OSX.
+    // 
+    // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
     pub struct Key<T> {
         // If `LazyKeyInner::get` returns `None`, that indicates either:
         //   * The value has never been initialized
@@ -403,38 +406,32 @@ pub mod fast {
             }
         }
 
-        #[inline]
         pub unsafe fn get<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
             match self.inner.get() {
                 Some(val) => Some(val),
-                None => {
-                    if mem::needs_drop::<T>() {
-                        self.try_initialize_drop(init)
-                    } else {
-                        Some(self.try_initialize_nodrop(init))
-                    }
-                }
+                None => self.try_initialize(init),
             }
         }
 
-        // `try_initialize_nodrop` is only called once per fast thread local
-        // variable, except in corner cases where it is being recursively
-        // initialized.
-        //
-        // Macos: Inlining this function causes two `tlv_get_addr` calls to be
-        // performed for every call to `Key::get`.
-        // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
-        #[inline(never)]
+        // `try_initialize` is only called once per fast thread local variable,
+        // except in corner cases where it is being recursively initialized.
         #[cold]
-        unsafe fn try_initialize_nodrop<F: FnOnce() -> T>(&self, init: F) -> &'static T {
-            self.inner.initialize(init)
+        unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
+            if mem::needs_drop::<T>() {
+                self.try_initialize_drop(init)
+            } else {
+                Some(self.inner.initialize(init))
+            }
         }
 
         // `try_initialize_drop` is only called once per fast thread local
         // variable, except in corner cases where thread_local dtors reference
         // other thread_local's, or it is being recursively initialized.
+        //
+        // Macos: Inlining this function causes two `tlv_get_addr` calls to be
+        // performed for every call to `Key::get`.
+        // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
         #[inline(never)]
-        #[cold]
         unsafe fn try_initialize_drop<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
             // We don't put a `needs_drop` check around this and call it a day
             // because this function is not inlined. Unwrapping code gets