Skip to content

Commit 0b5c087

Browse files
committed
Auto merge of #43584 - arielb1:unused-reads, r=eddyb
Fix quadratic performance with lots of use statements This fixes 2 problems that caused quadratic performance when lots of use-statements were present. After this patch, performance is linear (and very fast) even with 1M uses. Fixes #43572. Fixes #43573. r? @eddyb
2 parents 4f3062c + 70478ca commit 0b5c087

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

src/librustc/hir/map/definitions.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use hir;
1818
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
1919
CRATE_DEF_INDEX};
2020
use ich::Fingerprint;
21-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
21+
use rustc_data_structures::fx::FxHashMap;
2222
use rustc_data_structures::indexed_vec::IndexVec;
2323
use rustc_data_structures::stable_hasher::StableHasher;
2424
use serialize::{Encodable, Decodable, Encoder, Decoder};
@@ -153,7 +153,7 @@ pub struct Definitions {
153153
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
154154
macro_def_scopes: FxHashMap<Mark, DefId>,
155155
expansions: FxHashMap<DefIndex, Mark>,
156-
keys_created: FxHashSet<DefKey>,
156+
next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
157157
}
158158

159159
// Unfortunately we have to provide a manual impl of Clone because of the
@@ -170,7 +170,7 @@ impl Clone for Definitions {
170170
node_to_hir_id: self.node_to_hir_id.clone(),
171171
macro_def_scopes: self.macro_def_scopes.clone(),
172172
expansions: self.expansions.clone(),
173-
keys_created: self.keys_created.clone(),
173+
next_disambiguator: self.next_disambiguator.clone(),
174174
}
175175
}
176176
}
@@ -402,7 +402,7 @@ impl Definitions {
402402
node_to_hir_id: IndexVec::new(),
403403
macro_def_scopes: FxHashMap(),
404404
expansions: FxHashMap(),
405-
keys_created: FxHashSet(),
405+
next_disambiguator: FxHashMap(),
406406
}
407407
}
408408

@@ -516,21 +516,21 @@ impl Definitions {
516516
// The root node must be created with create_root_def()
517517
assert!(data != DefPathData::CrateRoot);
518518

519-
// Find a unique DefKey. This basically means incrementing the disambiguator
520-
// until we get no match.
521-
let mut key = DefKey {
519+
// Find the next free disambiguator for this key.
520+
let disambiguator = {
521+
let next_disamb = self.next_disambiguator.entry((parent, data.clone())).or_insert(0);
522+
let disambiguator = *next_disamb;
523+
*next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
524+
disambiguator
525+
};
526+
527+
let key = DefKey {
522528
parent: Some(parent),
523529
disambiguated_data: DisambiguatedDefPathData {
524-
data,
525-
disambiguator: 0
530+
data, disambiguator
526531
}
527532
};
528533

529-
while self.keys_created.contains(&key) {
530-
key.disambiguated_data.disambiguator += 1;
531-
}
532-
self.keys_created.insert(key.clone());
533-
534534
let parent_hash = self.table.def_path_hash(parent);
535535
let def_path_hash = key.compute_stable_hash(parent_hash);
536536

src/libsyntax/codemap.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,9 @@ impl CodeMapper for CodeMap {
561561
sp
562562
}
563563
fn ensure_filemap_source_present(&self, file_map: Rc<FileMap>) -> bool {
564-
let src = self.file_loader.read_file(Path::new(&file_map.name)).ok();
565-
return file_map.add_external_src(src)
564+
file_map.add_external_src(
565+
|| self.file_loader.read_file(Path::new(&file_map.name)).ok()
566+
)
566567
}
567568
}
568569

src/libsyntax_pos/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,11 @@ impl FileMap {
618618
/// If the hash of the input doesn't match or no input is supplied via None,
619619
/// it is interpreted as an error and the corresponding enum variant is set.
620620
/// The return value signifies whether some kind of source is present.
621-
pub fn add_external_src(&self, src: Option<String>) -> bool {
621+
pub fn add_external_src<F>(&self, get_src: F) -> bool
622+
where F: FnOnce() -> Option<String>
623+
{
622624
if *self.external_src.borrow() == ExternalSource::AbsentOk {
625+
let src = get_src();
623626
let mut external_src = self.external_src.borrow_mut();
624627
if let Some(src) = src {
625628
let mut hasher: StableHasher<u128> = StableHasher::new();

0 commit comments

Comments
 (0)