Skip to content

Commit 1a7f774

Browse files
committed
- 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
1 parent 060d8bb commit 1a7f774

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

src/libstd/thread/local.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ mod lazy {
275275
}
276276
}
277277

278-
#[inline]
279278
pub unsafe fn get(&self) -> Option<&'static T> {
280279
(*self.inner.get()).as_ref()
281280
}
@@ -346,7 +345,6 @@ pub mod statik {
346345
}
347346
}
348347

349-
#[inline]
350348
pub unsafe fn get(&self, init: fn() -> T) -> Option<&'static T> {
351349
let value = match self.inner.get() {
352350
Some(ref value) => value,
@@ -373,6 +371,11 @@ pub mod fast {
373371
RunningOrHasRun,
374372
}
375373

374+
// This data structure has been carefully constructed so that the fast path
375+
// only contains one branch on x86. That optimization is necessary to avoid
376+
// duplicated tls lookups on OSX.
377+
//
378+
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
376379
pub struct Key<T> {
377380
// If `LazyKeyInner::get` returns `None`, that indicates either:
378381
// * The value has never been initialized
@@ -403,38 +406,32 @@ pub mod fast {
403406
}
404407
}
405408

406-
#[inline]
407409
pub unsafe fn get<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
408410
match self.inner.get() {
409411
Some(val) => Some(val),
410-
None => {
411-
if mem::needs_drop::<T>() {
412-
self.try_initialize_drop(init)
413-
} else {
414-
Some(self.try_initialize_nodrop(init))
415-
}
416-
}
412+
None => self.try_initialize(init),
417413
}
418414
}
419415

420-
// `try_initialize_nodrop` is only called once per fast thread local
421-
// variable, except in corner cases where it is being recursively
422-
// initialized.
423-
//
424-
// Macos: Inlining this function causes two `tlv_get_addr` calls to be
425-
// performed for every call to `Key::get`.
426-
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
427-
#[inline(never)]
416+
// `try_initialize` is only called once per fast thread local variable,
417+
// except in corner cases where it is being recursively initialized.
428418
#[cold]
429-
unsafe fn try_initialize_nodrop<F: FnOnce() -> T>(&self, init: F) -> &'static T {
430-
self.inner.initialize(init)
419+
unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
420+
if mem::needs_drop::<T>() {
421+
self.try_initialize_drop(init)
422+
} else {
423+
Some(self.inner.initialize(init))
424+
}
431425
}
432426

433427
// `try_initialize_drop` is only called once per fast thread local
434428
// variable, except in corner cases where thread_local dtors reference
435429
// other thread_local's, or it is being recursively initialized.
430+
//
431+
// Macos: Inlining this function causes two `tlv_get_addr` calls to be
432+
// performed for every call to `Key::get`.
433+
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
436434
#[inline(never)]
437-
#[cold]
438435
unsafe fn try_initialize_drop<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
439436
// We don't put a `needs_drop` check around this and call it a day
440437
// because this function is not inlined. Unwrapping code gets

0 commit comments

Comments
 (0)