@@ -275,7 +275,6 @@ mod lazy {
275
275
}
276
276
}
277
277
278
- #[ inline]
279
278
pub unsafe fn get ( & self ) -> Option < & ' static T > {
280
279
( * self . inner . get ( ) ) . as_ref ( )
281
280
}
@@ -346,7 +345,6 @@ pub mod statik {
346
345
}
347
346
}
348
347
349
- #[ inline]
350
348
pub unsafe fn get ( & self , init : fn ( ) -> T ) -> Option < & ' static T > {
351
349
let value = match self . inner . get ( ) {
352
350
Some ( ref value) => value,
@@ -373,6 +371,11 @@ pub mod fast {
373
371
RunningOrHasRun ,
374
372
}
375
373
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
376
379
pub struct Key < T > {
377
380
// If `LazyKeyInner::get` returns `None`, that indicates either:
378
381
// * The value has never been initialized
@@ -403,38 +406,32 @@ pub mod fast {
403
406
}
404
407
}
405
408
406
- #[ inline]
407
409
pub unsafe fn get < F : FnOnce ( ) -> T > ( & self , init : F ) -> Option < & ' static T > {
408
410
match self . inner . get ( ) {
409
411
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) ,
417
413
}
418
414
}
419
415
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.
428
418
#[ 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
+ }
431
425
}
432
426
433
427
// `try_initialize_drop` is only called once per fast thread local
434
428
// variable, except in corner cases where thread_local dtors reference
435
429
// 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
436
434
#[ inline( never) ]
437
- #[ cold]
438
435
unsafe fn try_initialize_drop < F : FnOnce ( ) -> T > ( & self , init : F ) -> Option < & ' static T > {
439
436
// We don't put a `needs_drop` check around this and call it a day
440
437
// because this function is not inlined. Unwrapping code gets
0 commit comments