diff options
| author | tyler <tyler@brainiumstudios.com> | 2019-05-15 07:18:24 -0700 |
|---|---|---|
| committer | tyler <tyler@brainiumstudios.com> | 2019-05-15 07:30:34 -0700 |
| commit | 9289d03c9d263ac32a9dd0a5c581779fe1def7d3 (patch) | |
| tree | efd33e4523da7be0ee2c7d4bd64ccd0e5a726bcc /src/libstd/thread | |
| parent | 2b3642b95b04b4078405f4bc20ba537ce5512c00 (diff) | |
| download | rust-9289d03c9d263ac32a9dd0a5c581779fe1def7d3.tar.gz rust-9289d03c9d263ac32a9dd0a5c581779fe1def7d3.zip | |
llvm makes good inlining choices with only the #[cold] attribute
Diffstat (limited to 'src/libstd/thread')
| -rw-r--r-- | src/libstd/thread/local.rs | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 1a12457646a..733c772a1f5 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -414,46 +414,42 @@ pub mod fast { } // `try_initialize` is only called once per fast thread local variable, - // except in corner cases where it is being recursively initialized. + // except in corner cases where thread_local dtors reference other + // thread_local's, or it is being recursively initialized. + // + // Macos: Inlining this function can cause two `tlv_get_addr` calls to + // be performed for every call to `Key::get`. The #[cold] hint makes + // that less likely. + // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722 #[cold] unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> { - if mem::needs_drop::<T>() { - self.try_initialize_drop(init) - } else { + if !mem::needs_drop::<T>() || self.try_register_dtor() { Some(self.inner.initialize(init)) + } else { + None } } - // `try_initialize_drop` is only called once per fast thread local + // `try_register_dtor` 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 - // generated for callers of `LocalKey::with` even if we always - // return `Some` here. + unsafe fn try_register_dtor(&self) -> bool { match self.dtor_state.get() { DtorState::Unregistered => { // dtor registration happens before initialization. register_dtor(self as *const _ as *mut u8, destroy_value::<T>); self.dtor_state.set(DtorState::Registered); + true } DtorState::Registered => { // recursively initialized + true } DtorState::RunningOrHasRun => { - return None + false } } - - Some(self.inner.initialize(init)) } } |
