@@ -53,31 +53,38 @@ impl<T: Internable> Interned<T> {
53
53
}
54
54
55
55
impl < T : Internable + ?Sized > Drop for Interned < T > {
56
+ #[ inline]
56
57
fn drop ( & mut self ) {
57
58
// When the last `Ref` is dropped, remove the object from the global map.
58
59
if Arc :: strong_count ( & self . arc ) == 2 {
59
60
// Only `self` and the global map point to the object.
60
61
61
- let storage = T :: storage ( ) . get ( ) ;
62
- let shard_idx = storage. determine_map ( & self . arc ) ;
63
- let shard = & storage. shards ( ) [ shard_idx] ;
64
- let mut shard = shard. write ( ) ;
62
+ self . drop_slow ( ) ;
63
+ }
64
+ }
65
+ }
66
+
67
+ impl < T : Internable + ?Sized > Interned < T > {
68
+ #[ cold]
69
+ fn drop_slow ( & mut self ) {
70
+ let storage = T :: storage ( ) . get ( ) ;
71
+ let shard_idx = storage. determine_map ( & self . arc ) ;
72
+ let shard = & storage. shards ( ) [ shard_idx] ;
73
+ let mut shard = shard. write ( ) ;
65
74
66
- // FIXME: avoid double lookup
67
- let ( arc, _) =
68
- shard. get_key_value ( & self . arc ) . expect ( "interned value removed prematurely" ) ;
75
+ // FIXME: avoid double lookup
76
+ let ( arc, _) = shard. get_key_value ( & self . arc ) . expect ( "interned value removed prematurely" ) ;
69
77
70
- if Arc :: strong_count ( arc) != 2 {
71
- // Another thread has interned another copy
72
- return ;
73
- }
78
+ if Arc :: strong_count ( arc) != 2 {
79
+ // Another thread has interned another copy
80
+ return ;
81
+ }
74
82
75
- shard. remove ( & self . arc ) ;
83
+ shard. remove ( & self . arc ) ;
76
84
77
- // Shrink the backing storage if the shard is less than 50% occupied.
78
- if shard. len ( ) * 2 < shard. capacity ( ) {
79
- shard. shrink_to_fit ( ) ;
80
- }
85
+ // Shrink the backing storage if the shard is less than 50% occupied.
86
+ if shard. len ( ) * 2 < shard. capacity ( ) {
87
+ shard. shrink_to_fit ( ) ;
81
88
}
82
89
}
83
90
}
0 commit comments