@@ -414,46 +414,42 @@ pub mod fast {
414414 }
415415
416416 // `try_initialize` is only called once per fast thread local variable,
417- // except in corner cases where it is being recursively initialized.
417+ // except in corner cases where thread_local dtors reference other
418+ // thread_local's, or it is being recursively initialized.
419+ //
420+ // Macos: Inlining this function can cause two `tlv_get_addr` calls to
421+ // be performed for every call to `Key::get`. The #[cold] hint makes
422+ // that less likely.
423+ // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
418424 #[ cold]
419425 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 {
426+ if !mem:: needs_drop :: < T > ( ) || self . try_register_dtor ( ) {
423427 Some ( self . inner . initialize ( init) )
428+ } else {
429+ None
424430 }
425431 }
426432
427- // `try_initialize_drop ` is only called once per fast thread local
433+ // `try_register_dtor ` is only called once per fast thread local
428434 // variable, except in corner cases where thread_local dtors reference
429435 // 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
434- #[ inline( never) ]
435- #[ cold]
436- unsafe fn try_initialize_drop < F : FnOnce ( ) -> T > ( & self , init : F ) -> Option < & ' static T > {
437- // We don't put a `needs_drop` check around this and call it a day
438- // because this function is not inlined. Unwrapping code gets
439- // generated for callers of `LocalKey::with` even if we always
440- // return `Some` here.
436+ unsafe fn try_register_dtor ( & self ) -> bool {
441437 match self . dtor_state . get ( ) {
442438 DtorState :: Unregistered => {
443439 // dtor registration happens before initialization.
444440 register_dtor ( self as * const _ as * mut u8 ,
445441 destroy_value :: < T > ) ;
446442 self . dtor_state . set ( DtorState :: Registered ) ;
443+ true
447444 }
448445 DtorState :: Registered => {
449446 // recursively initialized
447+ true
450448 }
451449 DtorState :: RunningOrHasRun => {
452- return None
450+ false
453451 }
454452 }
455-
456- Some ( self . inner . initialize ( init) )
457453 }
458454 }
459455
0 commit comments