Skip to content

Commit a16a6f1

Browse files
committed
Avoid indexing the owners table all the time
1 parent 6f7f469 commit a16a6f1

File tree

6 files changed

+100
-59
lines changed

6 files changed

+100
-59
lines changed

Diff for: compiler/rustc_ast_lowering/src/lib.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ struct LoweringContext<'a, 'hir> {
125125
is_in_dyn_type: bool,
126126

127127
current_hir_id_owner: hir::OwnerId,
128-
current_ast_id_owner: NodeId,
128+
current_ast_id_owner: PerOwnerResolverData,
129129
item_local_id_counter: hir::ItemLocalId,
130130
trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
131131

@@ -164,7 +164,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164164
children: Vec::default(),
165165
contract_ensures: None,
166166
current_hir_id_owner: hir::CRATE_OWNER_ID,
167-
current_ast_id_owner: CRATE_NODE_ID,
167+
current_ast_id_owner: PerOwnerResolverData {
168+
node_id_to_def_id: Default::default(),
169+
id: DUMMY_NODE_ID,
170+
},
168171
item_local_id_counter: hir::ItemLocalId::ZERO,
169172
ident_and_label_to_local_id: Default::default(),
170173
#[cfg(debug_assertions)]
@@ -535,12 +538,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
535538
self.tcx.at(span).create_def(self.current_hir_id_owner.def_id, name, def_kind).def_id();
536539

537540
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
538-
self.resolver
539-
.owners
540-
.get_mut(&self.current_ast_id_owner)
541-
.unwrap()
542-
.node_id_to_def_id
543-
.insert(node_id, def_id);
541+
self.current_ast_id_owner.node_id_to_def_id.insert(node_id, def_id);
544542

545543
def_id
546544
}
@@ -555,7 +553,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
555553
/// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
556554
/// resolver (if any).
557555
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
558-
self.resolver.owners[&self.current_ast_id_owner].node_id_to_def_id.get(&node).copied()
556+
self.current_ast_id_owner.node_id_to_def_id.get(&node).copied()
559557
}
560558

561559
fn local_def_id(&self, node: NodeId) -> LocalDefId {
@@ -564,10 +562,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
564562
items.node_id_to_def_id.items().any(|(node_id, def_id)| {
565563
if *node_id == node {
566564
panic!(
567-
"{def_id:?} ({node_id}) was found in {:?} ({id}) instead of in {:?} ({})",
565+
"{def_id:?} ({node_id}) was found in {:?} ({id})",
568566
items.node_id_to_def_id.get(id),
569-
self.resolver.owners[&self.current_ast_id_owner].node_id_to_def_id[&self.current_ast_id_owner],
570-
self.current_ast_id_owner,
571567
)
572568
}
573569
false
@@ -598,7 +594,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
598594
let current_attrs = std::mem::take(&mut self.attrs);
599595
let current_bodies = std::mem::take(&mut self.bodies);
600596
let current_define_opaque = std::mem::take(&mut self.define_opaque);
601-
let current_ast_owner = std::mem::replace(&mut self.current_ast_id_owner, owner);
597+
let current_ast_owner = std::mem::replace(
598+
&mut self.current_ast_id_owner,
599+
self.resolver.owners.remove(&owner).unwrap(),
600+
);
602601
let current_ident_and_label_to_local_id =
603602
std::mem::take(&mut self.ident_and_label_to_local_id);
604603

Diff for: compiler/rustc_middle/src/ty/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,17 @@ pub struct ResolverGlobalCtxt {
187187
pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
188188
}
189189

190-
#[derive(Debug, Default)]
190+
#[derive(Debug)]
191191
pub struct PerOwnerResolverData {
192192
pub node_id_to_def_id: NodeMap<LocalDefId>,
193+
/// The id of the owner
194+
pub id: ast::NodeId,
195+
}
196+
197+
impl PerOwnerResolverData {
198+
pub fn new(id: ast::NodeId) -> Self {
199+
Self { node_id_to_def_id: Default::default(), id }
200+
}
193201
}
194202

195203
/// Resolutions that should only be used for lowering.

Diff for: compiler/rustc_resolve/src/def_collector.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_expand::expand::AstFragment;
88
use rustc_hir as hir;
99
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
1010
use rustc_hir::def_id::LocalDefId;
11+
use rustc_middle::ty::PerOwnerResolverData;
1112
use rustc_span::hygiene::LocalExpnId;
1213
use rustc_span::{Span, Symbol, sym};
1314
use tracing::debug;
@@ -20,10 +21,13 @@ pub(crate) fn collect_definitions(
2021
expansion: LocalExpnId,
2122
) {
2223
let invocation_parent = resolver.invocation_parents[&expansion];
23-
resolver.current_owner = invocation_parent.owner;
24+
assert_eq!(resolver.current_owner.id, DUMMY_NODE_ID);
25+
resolver.current_owner = resolver.owners.remove(&invocation_parent.owner).unwrap();
2426
let mut visitor = DefCollector { resolver, expansion, invocation_parent };
2527
fragment.visit_with(&mut visitor);
26-
resolver.current_owner = DUMMY_NODE_ID;
28+
let tables =
29+
mem::replace(&mut resolver.current_owner, PerOwnerResolverData::new(DUMMY_NODE_ID));
30+
assert!(resolver.owners.insert(invocation_parent.owner, tables).is_none());
2731
}
2832

2933
/// Creates `DefId`s for nodes in the AST.
@@ -68,12 +72,21 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
6872
}
6973

7074
fn with_owner<F: FnOnce(&mut Self)>(&mut self, owner: NodeId, f: F) {
71-
let orig_owner = mem::replace(&mut self.resolver.current_owner, owner);
72-
let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner);
7375
assert_ne!(owner, DUMMY_NODE_ID);
74-
self.resolver.owners.entry(owner).or_default();
76+
if owner == CRATE_NODE_ID {
77+
// Special case: we always have an invocation parent of at least the crate root,
78+
// even for visiting the crate root, which would then remove the crate root from the tables
79+
// list twice and try to insert it twice afterwards.
80+
assert_eq!(self.resolver.current_owner.id, CRATE_NODE_ID);
81+
return f(self);
82+
}
83+
let tables =
84+
self.resolver.owners.remove(&owner).unwrap_or_else(|| PerOwnerResolverData::new(owner));
85+
let orig_owner = mem::replace(&mut self.resolver.current_owner, tables);
86+
let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner);
7587
f(self);
76-
assert_eq!(mem::replace(&mut self.resolver.current_owner, orig_owner), owner);
88+
let tables = mem::replace(&mut self.resolver.current_owner, orig_owner);
89+
assert!(self.resolver.owners.insert(owner, tables).is_none());
7790
assert_eq!(mem::replace(&mut self.invocation_parent.owner, orig_invoc_owner), owner);
7891
}
7992

Diff for: compiler/rustc_resolve/src/late.rs

+19-16
Original file line numberDiff line numberDiff line change
@@ -1688,9 +1688,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
16881688

16891689
#[instrument(level = "debug", skip(self, work))]
16901690
fn with_owner<T>(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T {
1691-
let old_owner = std::mem::replace(&mut self.r.current_owner, owner);
1691+
let old_owner =
1692+
std::mem::replace(&mut self.r.current_owner, self.r.owners.remove(&owner).unwrap());
16921693
let ret = work(self);
1693-
self.r.current_owner = old_owner;
1694+
let prev = std::mem::replace(&mut self.r.current_owner, old_owner);
1695+
self.r.owners.insert(prev.id, prev);
16941696
ret
16951697
}
16961698

@@ -5239,20 +5241,21 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
52395241

52405242
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
52415243
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
5242-
self.current_owner = CRATE_NODE_ID;
5243-
visit::walk_crate(&mut ItemInfoCollector { r: self }, krate);
5244-
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
5245-
late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
5246-
visit::walk_crate(&mut late_resolution_visitor, krate);
5247-
for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() {
5248-
self.lint_buffer.buffer_lint(
5249-
lint::builtin::UNUSED_LABELS,
5250-
*id,
5251-
*span,
5252-
BuiltinLintDiag::UnusedLabel,
5253-
);
5254-
}
5255-
self.current_owner = DUMMY_NODE_ID;
5244+
self.with_owner(CRATE_NODE_ID, |this| {
5245+
visit::walk_crate(&mut ItemInfoCollector { r: this }, krate);
5246+
let mut late_resolution_visitor = LateResolutionVisitor::new(this);
5247+
late_resolution_visitor
5248+
.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
5249+
visit::walk_crate(&mut late_resolution_visitor, krate);
5250+
for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() {
5251+
this.lint_buffer.buffer_lint(
5252+
lint::builtin::UNUSED_LABELS,
5253+
*id,
5254+
*span,
5255+
BuiltinLintDiag::UnusedLabel,
5256+
);
5257+
}
5258+
})
52565259
}
52575260
}
52585261

Diff for: compiler/rustc_resolve/src/lib.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,8 @@ pub struct Resolver<'ra, 'tcx> {
10641064
/// Preserves per owner data once the owner is finished resolving.
10651065
owners: NodeMap<PerOwnerResolverData>,
10661066

1067-
/// Used to index into [Self::owners]. Refers to the owner of the nodes that are currently processed
1068-
current_owner: NodeId,
1067+
/// An entry of `owners` that gets taken out and reinserted whenever an owner is handled.
1068+
current_owner: PerOwnerResolverData,
10691069

10701070
/// Resolutions for nodes that have a single resolution.
10711071
partial_res_map: NodeMap<PartialRes>,
@@ -1240,19 +1240,17 @@ pub struct Resolver<'ra, 'tcx> {
12401240

12411241
impl<'ra, 'tcx> std::ops::DerefMut for Resolver<'ra, 'tcx> {
12421242
fn deref_mut(&mut self) -> &mut Self::Target {
1243-
assert_ne!(self.current_owner, DUMMY_NODE_ID);
1244-
self.owners
1245-
.get_mut(&self.current_owner)
1246-
.unwrap_or_else(|| panic!("no entry for {}", self.current_owner))
1243+
assert_ne!(self.current_owner.id, DUMMY_NODE_ID);
1244+
&mut self.current_owner
12471245
}
12481246
}
12491247

12501248
impl<'ra, 'tcx> std::ops::Deref for Resolver<'ra, 'tcx> {
12511249
type Target = PerOwnerResolverData;
12521250

12531251
fn deref(&self) -> &Self::Target {
1254-
assert_ne!(self.current_owner, DUMMY_NODE_ID);
1255-
&self.owners[&self.current_owner]
1252+
assert_ne!(self.current_owner.id, DUMMY_NODE_ID);
1253+
&self.current_owner
12561254
}
12571255
}
12581256

@@ -1445,7 +1443,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14451443
let mut def_id_to_node_id = IndexVec::default();
14461444
assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
14471445
let mut feed_for_node_id = NodeMap::default();
1448-
let mut owner_data = PerOwnerResolverData::default();
1446+
let mut owner_data = PerOwnerResolverData::new(CRATE_NODE_ID);
14491447
let crate_feed = tcx.create_local_crate_def_id(crate_span);
14501448

14511449
crate_feed.def_kind(DefKind::Mod);
@@ -1498,7 +1496,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14981496

14991497
pat_span_map: Default::default(),
15001498
owners,
1501-
current_owner: DUMMY_NODE_ID,
1499+
current_owner: PerOwnerResolverData::new(DUMMY_NODE_ID),
15021500
partial_res_map: Default::default(),
15031501
import_res_map: Default::default(),
15041502
import_use_map: Default::default(),
@@ -2291,9 +2289,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22912289

22922290
#[instrument(level = "debug", skip(self, work))]
22932291
fn with_owner<T>(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T {
2294-
let old_owner = std::mem::replace(&mut self.current_owner, owner);
2292+
let old_owner =
2293+
std::mem::replace(&mut self.current_owner, self.owners.remove(&owner).unwrap());
22952294
let ret = work(self);
2296-
assert_eq!(std::mem::replace(&mut self.current_owner, old_owner), owner);
2295+
assert!(
2296+
self.owners
2297+
.insert(owner, std::mem::replace(&mut self.current_owner, old_owner))
2298+
.is_none()
2299+
);
22972300
ret
22982301
}
22992302
}

Diff for: compiler/rustc_resolve/src/macros.rs

+26-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_expand::expand::{
2121
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
2222
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
2323
use rustc_middle::middle::stability;
24-
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
24+
use rustc_middle::ty::{PerOwnerResolverData, RegisteredTools, TyCtxt, Visibility};
2525
use rustc_session::lint::BuiltinLintDiag;
2626
use rustc_session::lint::builtin::{
2727
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
@@ -511,19 +511,34 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
511511

512512
fn set_owner(&mut self, id: NodeId) -> NodeId {
513513
assert_ne!(id, DUMMY_NODE_ID);
514-
let old = std::mem::replace(&mut self.current_owner, id);
515-
self.owners.entry(id).or_default();
516-
old
514+
let old = std::mem::replace(
515+
&mut self.current_owner,
516+
self.owners.remove(&id).unwrap_or_else(|| PerOwnerResolverData {
517+
node_id_to_def_id: Default::default(),
518+
id,
519+
}),
520+
);
521+
let old_id = old.id;
522+
if old.id == DUMMY_NODE_ID {
523+
if cfg!(debug_assertions) {
524+
let PerOwnerResolverData { node_id_to_def_id, id: _ } = old;
525+
assert!(node_id_to_def_id.is_empty());
526+
}
527+
} else {
528+
assert!(self.owners.insert(old.id, old).is_none());
529+
}
530+
old_id
517531
}
518532

519533
fn reset_owner(&mut self, id: NodeId) {
520-
let old = std::mem::replace(&mut self.current_owner, id);
521-
if cfg!(debug_assertions) {
522-
if id != DUMMY_NODE_ID {
523-
self.owners.get(&id).unwrap();
524-
}
525-
self.owners.get(&old).unwrap();
526-
}
534+
let new = if id == DUMMY_NODE_ID {
535+
PerOwnerResolverData { node_id_to_def_id: Default::default(), id: DUMMY_NODE_ID }
536+
} else {
537+
self.owners.remove(&id).unwrap()
538+
};
539+
let old = std::mem::replace(&mut self.current_owner, new);
540+
assert_ne!(old.id, DUMMY_NODE_ID);
541+
assert!(self.owners.insert(old.id, old).is_none());
527542
}
528543
}
529544

0 commit comments

Comments
 (0)