diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index 70524bae624a..f9f5871c8d61 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs @@ -359,6 +359,10 @@ where } } } + + pub fn len(&self) -> usize { + self.len.load(Ordering::Acquire) + } } #[cfg(test)] diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 48e2ee8e9abd..449dc95ea372 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -508,6 +508,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // Unresolved macros produce dummy outputs as a recovery measure. invocations.reverse(); let mut expanded_fragments = Vec::new(); + let mut expanded_fragments_len = 0; let mut undetermined_invocations = Vec::new(); let (mut progress, mut force) = (false, !self.monotonic); loop { @@ -602,6 +603,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { expanded_fragments.push(Vec::new()); } expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); + expanded_fragments_len += 1; invocations.extend(derive_invocations.into_iter().rev()); } ExpandResult::Retry(invoc) => { @@ -622,7 +624,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.force_mode = orig_force_mode; // Finally incorporate all the expanded macros into the input AST fragment. - let mut placeholder_expander = PlaceholderExpander::default(); + let mut placeholder_expander = PlaceholderExpander::with_capacity(expanded_fragments_len); while let Some(expanded_fragments) = expanded_fragments.pop() { for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() { placeholder_expander diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 05f9a5aa43f7..2db18429a521 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -218,12 +218,17 @@ pub(crate) fn placeholder( } } -#[derive(Default)] pub(crate) struct PlaceholderExpander { expanded_fragments: FxHashMap, } impl PlaceholderExpander { + pub(crate) fn with_capacity(capacity: usize) -> Self { + PlaceholderExpander { + expanded_fragments: FxHashMap::with_capacity_and_hasher(capacity, Default::default()), + } + } + pub(crate) fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) { fragment.mut_visit_with(self); self.expanded_fragments.insert(id, fragment); diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index d1721f1f455f..3835f3f557a6 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -410,9 +410,8 @@ pub(crate) fn query_key_hash_verify<'tcx>( ) { let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name()); - let mut map = UnordMap::default(); - let cache = query.query_cache(qcx); + let mut map = UnordMap::with_capacity(cache.len()); cache.iter(&mut |key, _, _| { let node = DepNode::construct(qcx.tcx, query.dep_kind(), key); if let Some(other_key) = map.insert(node, *key) { diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 30b5d7e59549..67ad767d4d31 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -30,6 +30,8 @@ pub trait QueryCache: Sized { fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex); fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); + + fn len(&self) -> usize; } /// In-memory cache for queries whose keys aren't suitable for any of the @@ -71,6 +73,10 @@ where } } } + + fn len(&self) -> usize { + self.cache.len() + } } /// In-memory cache for queries whose key type only has one value (e.g. `()`). @@ -107,6 +113,10 @@ where f(&(), &value.0, value.1) } } + + fn len(&self) -> usize { + self.cache.get().is_some().into() + } } /// In-memory cache for queries whose key is a [`DefId`]. @@ -157,6 +167,10 @@ where }); self.foreign.iter(f); } + + fn len(&self) -> usize { + self.local.len() + self.foreign.len() + } } impl QueryCache for VecCache @@ -180,4 +194,8 @@ where fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { self.iter(f) } + + fn len(&self) -> usize { + self.len() + } }