@@ -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