Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/span/src/ast_id.rs')
| -rw-r--r-- | crates/span/src/ast_id.rs | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/crates/span/src/ast_id.rs b/crates/span/src/ast_id.rs index e54e0bd2fc..599b3c7175 100644 --- a/crates/span/src/ast_id.rs +++ b/crates/span/src/ast_id.rs @@ -603,8 +603,9 @@ impl AstIdMap { // After all, the block will then contain the *outer* item, so we allocate // an ID for it anyway. let mut blocks = Vec::new(); - let mut curr_layer = vec![(node.clone(), None)]; - let mut next_layer = vec![]; + let mut curr_layer = Vec::with_capacity(32); + curr_layer.push((node.clone(), None)); + let mut next_layer = Vec::with_capacity(32); while !curr_layer.is_empty() { curr_layer.drain(..).for_each(|(node, parent_idx)| { let mut preorder = node.preorder(); @@ -776,6 +777,48 @@ impl AstIdMap { } } +#[cfg(not(no_salsa_async_drops))] +impl Drop for AstIdMap { + fn drop(&mut self) { + let arena = std::mem::take(&mut self.arena); + let ptr_map = std::mem::take(&mut self.ptr_map); + let id_map = std::mem::take(&mut self.id_map); + static AST_ID_MAP_DROP_THREAD: std::sync::OnceLock< + std::sync::mpsc::Sender<( + Arena<(SyntaxNodePtr, ErasedFileAstId)>, + hashbrown::HashTable<ArenaId>, + hashbrown::HashTable<ArenaId>, + )>, + > = std::sync::OnceLock::new(); + AST_ID_MAP_DROP_THREAD + .get_or_init(|| { + let (sender, receiver) = std::sync::mpsc::channel::<( + Arena<(SyntaxNodePtr, ErasedFileAstId)>, + hashbrown::HashTable<ArenaId>, + hashbrown::HashTable<ArenaId>, + )>(); + std::thread::Builder::new() + .name("AstIdMapDropper".to_owned()) + .spawn(move || { + loop { + // block on a receive + _ = receiver.recv(); + // then drain the entire channel + while receiver.try_recv().is_ok() {} + // and sleep for a bit + std::thread::sleep(std::time::Duration::from_millis(100)); + } + // why do this over just a `receiver.iter().for_each(drop)`? To reduce contention on the channel lock. + // otherwise this thread will constantly wake up and sleep again. + }) + .unwrap(); + sender + }) + .send((arena, ptr_map, id_map)) + .unwrap(); + } +} + #[inline] fn hash_ptr(ptr: &SyntaxNodePtr) -> u64 { FxBuildHasher.hash_one(ptr) |