Split Intern::drop
into hot and cold path
This commit is contained in:
parent
afd83e0686
commit
76452956e4
1 changed files with 23 additions and 16 deletions
|
@ -53,19 +53,27 @@ impl<T: Internable> Interned<T> {
|
|||
}
|
||||
|
||||
impl<T: Internable + ?Sized> Drop for Interned<T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
// When the last `Ref` is dropped, remove the object from the global map.
|
||||
if Arc::strong_count(&self.arc) == 2 {
|
||||
// Only `self` and the global map point to the object.
|
||||
|
||||
self.drop_slow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Internable + ?Sized> Interned<T> {
|
||||
#[cold]
|
||||
fn drop_slow(&mut self) {
|
||||
let storage = T::storage().get();
|
||||
let shard_idx = storage.determine_map(&self.arc);
|
||||
let shard = &storage.shards()[shard_idx];
|
||||
let mut shard = shard.write();
|
||||
|
||||
// FIXME: avoid double lookup
|
||||
let (arc, _) =
|
||||
shard.get_key_value(&self.arc).expect("interned value removed prematurely");
|
||||
let (arc, _) = shard.get_key_value(&self.arc).expect("interned value removed prematurely");
|
||||
|
||||
if Arc::strong_count(arc) != 2 {
|
||||
// Another thread has interned another copy
|
||||
|
@ -80,7 +88,6 @@ impl<T: Internable + ?Sized> Drop for Interned<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compares interned `Ref`s using pointer equality.
|
||||
impl<T: Internable + ?Sized> PartialEq for Interned<T> {
|
||||
|
|
Loading…
Reference in a new issue