diff options
| author | tyler <tyler@brainiumstudios.com> | 2019-04-27 08:01:32 -0700 |
|---|---|---|
| committer | tyler <tyler@brainiumstudios.com> | 2019-05-15 07:30:33 -0700 |
| commit | 430a091cd80c0e4b6bf44f6a19463a832e566f97 (patch) | |
| tree | 9c9d3baeed0c0eab8d434a76b41148997d42611a /src/libstd | |
| parent | ae4be16e407061828fe604b1ccbd61181b14a3f1 (diff) | |
| download | rust-430a091cd80c0e4b6bf44f6a19463a832e566f97.tar.gz rust-430a091cd80c0e4b6bf44f6a19463a832e566f97.zip | |
ensure fast thread local lookups occur once per access on macos
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/redox/fast_thread_local.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fast_thread_local.rs | 17 | ||||
| -rw-r--r-- | src/libstd/sys/windows/fast_thread_local.rs | 4 | ||||
| -rw-r--r-- | src/libstd/thread/local.rs | 11 |
4 files changed, 32 insertions, 6 deletions
diff --git a/src/libstd/sys/redox/fast_thread_local.rs b/src/libstd/sys/redox/fast_thread_local.rs index 67b92d490b2..c34cd575db7 100644 --- a/src/libstd/sys/redox/fast_thread_local.rs +++ b/src/libstd/sys/redox/fast_thread_local.rs @@ -1,4 +1,8 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "0")] -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; \ No newline at end of file +pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; + +pub unsafe fn lookup_once<T>(ptr: *const &T) -> &T { + *ptr +} diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs index c34c2e6e786..28fb9800541 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/fast_thread_local.rs @@ -82,3 +82,20 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) { } } } + +#[cfg(not(target_os = "macos"))] +pub unsafe fn lookup_once<T>(ptr: *const &T) -> &T { + *ptr +} + +#[cfg(target_os = "macos")] +pub unsafe fn lookup_once<T>(ptr: *const &T) -> &T { + // On macos, thread_local lookups can result in terrible code due to + // aggressive rerunning of the macos equivalent of `__tls_get_addr` - four + // lookups per actual reference in user code. + // + // Using a read_volatile on a value holding fast Key's address tricks the + // optimizer into only calling the macos get_addr equivalent once per time + // requested by the user. + crate::ptr::read_volatile(ptr) +} diff --git a/src/libstd/sys/windows/fast_thread_local.rs b/src/libstd/sys/windows/fast_thread_local.rs index 31d0bd1e72e..566d5524fd7 100644 --- a/src/libstd/sys/windows/fast_thread_local.rs +++ b/src/libstd/sys/windows/fast_thread_local.rs @@ -2,3 +2,7 @@ #![cfg(target_thread_local)] pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; + +pub unsafe fn lookup_once<T>(ptr: *const &T) -> &T { + *ptr +} diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 0d5e1f2af38..9ce2fcf2352 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -344,7 +344,7 @@ pub mod fast { use crate::fmt; use crate::mem; use crate::ptr; - use crate::sys::fast_thread_local::register_dtor; + use crate::sys::fast_thread_local::{lookup_once, register_dtor}; pub struct Key<T> { inner: UnsafeCell<Option<T>>, @@ -371,11 +371,12 @@ pub mod fast { } pub unsafe fn get(&self) -> Option<&'static UnsafeCell<Option<T>>> { - if mem::needs_drop::<T>() && self.dtor_running.get() { + let this = lookup_once(&self); + if mem::needs_drop::<T>() && this.dtor_running.get() { return None } - self.register_dtor(); - Some(&*(&self.inner as *const _)) + this.register_dtor(); + Some(&*(&this.inner as *const _)) } unsafe fn register_dtor(&self) { @@ -395,7 +396,7 @@ pub mod fast { // destructor as running for this thread so calls to `get` will return // `None`. (*ptr).dtor_running.set(true); - + ptr::drop_in_place((*ptr).inner.get()); } } |
