Skip to content

Commit d6cd2c6

Browse files
committed
Auto merge of #82183 - michaelwoerister:lazier-defpathhash-loading2, r=wesleywiser
Simplify lazy DefPathHash decoding by using an on-disk hash table. This PR simplifies the logic around mapping `DefPathHash` values encountered during incremental compilation to valid `DefId`s in the current session. It is able to do so by using an on-disk hash table encoding that allows for looking up values directly, i.e. without deserializing the entire table. The main simplification comes from not having to keep track of `DefPathHashes` being used during the compilation session.
2 parents 23afad6 + 4d151d9 commit d6cd2c6

File tree

22 files changed

+279
-350
lines changed

22 files changed

+279
-350
lines changed

Cargo.lock

+11
Original file line numberDiff line numberDiff line change
@@ -2321,6 +2321,15 @@ dependencies = [
23212321
"rustc-std-workspace-core",
23222322
]
23232323

2324+
[[package]]
2325+
name = "odht"
2326+
version = "0.2.1"
2327+
source = "registry+https://github.com/rust-lang/crates.io-index"
2328+
checksum = "0b18a8d1c919d3e7b5c49708d08ef7d60bc2150a7c3a8244257c54ca3f625010"
2329+
dependencies = [
2330+
"cfg-if 1.0.0",
2331+
]
2332+
23242333
[[package]]
23252334
name = "once_cell"
23262335
version = "1.7.2"
@@ -3859,6 +3868,7 @@ version = "0.0.0"
38593868
name = "rustc_hir"
38603869
version = "0.0.0"
38613870
dependencies = [
3871+
"odht",
38623872
"rustc_ast",
38633873
"rustc_data_structures",
38643874
"rustc_feature",
@@ -4045,6 +4055,7 @@ name = "rustc_metadata"
40454055
version = "0.0.0"
40464056
dependencies = [
40474057
"libc",
4058+
"odht",
40484059
"rustc_ast",
40494060
"rustc_attr",
40504061
"rustc_data_structures",

compiler/rustc_hir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ rustc_serialize = { path = "../rustc_serialize" }
1717
rustc_ast = { path = "../rustc_ast" }
1818
tracing = "0.1"
1919
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
20+
odht = { version = "0.2.1", features = ["nightly"] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use rustc_data_structures::fingerprint::Fingerprint;
2+
use rustc_span::def_id::{DefIndex, DefPathHash};
3+
4+
#[derive(Clone, Default)]
5+
pub struct Config;
6+
7+
impl odht::Config for Config {
8+
type Key = DefPathHash;
9+
type Value = DefIndex;
10+
11+
type EncodedKey = [u8; 16];
12+
type EncodedValue = [u8; 4];
13+
14+
type H = odht::UnHashFn;
15+
16+
#[inline]
17+
fn encode_key(k: &DefPathHash) -> [u8; 16] {
18+
k.0.to_le_bytes()
19+
}
20+
21+
#[inline]
22+
fn encode_value(v: &DefIndex) -> [u8; 4] {
23+
v.as_u32().to_le_bytes()
24+
}
25+
26+
#[inline]
27+
fn decode_key(k: &[u8; 16]) -> DefPathHash {
28+
DefPathHash(Fingerprint::from_le_bytes(*k))
29+
}
30+
31+
#[inline]
32+
fn decode_value(v: &[u8; 4]) -> DefIndex {
33+
DefIndex::from_u32(u32::from_le_bytes(*v))
34+
}
35+
}
36+
37+
pub type DefPathHashMap = odht::HashTableOwned<Config>;

compiler/rustc_hir/src/definitions.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
77
pub use crate::def_id::DefPathHash;
88
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
9+
use crate::def_path_hash_map::DefPathHashMap;
910
use crate::hir;
1011

1112
use rustc_data_structures::fx::FxHashMap;
1213
use rustc_data_structures::stable_hasher::StableHasher;
13-
use rustc_data_structures::unhash::UnhashMap;
1414
use rustc_index::vec::IndexVec;
1515
use rustc_span::hygiene::ExpnId;
1616
use rustc_span::symbol::{kw, sym, Symbol};
@@ -28,7 +28,7 @@ use tracing::debug;
2828
pub struct DefPathTable {
2929
index_to_key: IndexVec<DefIndex, DefKey>,
3030
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
31-
def_path_hash_to_index: UnhashMap<DefPathHash, DefIndex>,
31+
def_path_hash_to_index: DefPathHashMap,
3232
}
3333

3434
impl DefPathTable {
@@ -44,7 +44,7 @@ impl DefPathTable {
4444

4545
// Check for hash collisions of DefPathHashes. These should be
4646
// exceedingly rare.
47-
if let Some(existing) = self.def_path_hash_to_index.insert(def_path_hash, index) {
47+
if let Some(existing) = self.def_path_hash_to_index.insert(&def_path_hash, &index) {
4848
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx));
4949
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx));
5050

@@ -87,7 +87,7 @@ impl DefPathTable {
8787

8888
pub fn enumerated_keys_and_path_hashes(
8989
&self,
90-
) -> impl Iterator<Item = (DefIndex, &DefKey, &DefPathHash)> + '_ {
90+
) -> impl Iterator<Item = (DefIndex, &DefKey, &DefPathHash)> + ExactSizeIterator + '_ {
9191
self.index_to_key
9292
.iter_enumerated()
9393
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
@@ -110,6 +110,9 @@ pub struct Definitions {
110110
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
111111

112112
def_id_to_span: IndexVec<LocalDefId, Span>,
113+
114+
/// The [StableCrateId] of the local crate.
115+
stable_crate_id: StableCrateId,
113116
}
114117

115118
/// A unique identifier that we can use to lookup a definition
@@ -356,6 +359,7 @@ impl Definitions {
356359
hir_id_to_def_id: Default::default(),
357360
expansions_that_defined: Default::default(),
358361
def_id_to_span,
362+
stable_crate_id,
359363
}
360364
}
361365

@@ -439,11 +443,17 @@ impl Definitions {
439443
}
440444

441445
#[inline(always)]
442-
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
446+
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> LocalDefId {
447+
debug_assert!(hash.stable_crate_id() == self.stable_crate_id);
443448
self.table
444449
.def_path_hash_to_index
445450
.get(&hash)
446-
.map(|&local_def_index| LocalDefId { local_def_index })
451+
.map(|local_def_index| LocalDefId { local_def_index })
452+
.unwrap()
453+
}
454+
455+
pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {
456+
&self.table.def_path_hash_to_index
447457
}
448458
}
449459

compiler/rustc_hir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extern crate rustc_data_structures;
1616

1717
mod arena;
1818
pub mod def;
19+
pub mod def_path_hash_map;
1920
pub mod definitions;
2021
pub use rustc_span::def_id;
2122
mod hir;

compiler/rustc_metadata/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ doctest = false
88

99
[dependencies]
1010
libc = "0.2"
11+
odht = { version = "0.2.1", features = ["nightly"] }
1112
snap = "1"
1213
tracing = "0.1"
1314
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }

compiler/rustc_metadata/src/creader.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct CStore {
4545

4646
/// This map is used to verify we get no hash conflicts between
4747
/// `StableCrateId` values.
48-
stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
48+
pub(crate) stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
4949

5050
/// Unused externs of the crate
5151
unused_externs: Vec<Symbol>,

0 commit comments

Comments
 (0)