From 0debea1377459e34b39bdbb5095d9e33cced9912 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 20 Jul 2021 13:51:21 +0200 Subject: [PATCH 01/10] Allow taking an OwningRef of the crate metadata blob. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 78 +++++++++++++++----- compiler/rustc_metadata/src/rmeta/table.rs | 2 +- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2a0332a11242e..06b3ef2add21b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -48,7 +48,26 @@ use rustc_span::hygiene::HygieneDecodeContext; mod cstore_impl; -crate struct MetadataBlob(MetadataRef); +/// A reference to the raw binary version of crate metadata. +/// A `MetadataBlob` internally is just a reference counted pointer to +/// the actual data, so cloning it is cheap. +#[derive(Clone)] +crate struct MetadataBlob(Lrc); + +// This is needed so we can create an OwningRef into the blob. +// The data behind a `MetadataBlob` has a stable address because it +// contained within an Rc/Arc. +unsafe impl rustc_data_structures::owning_ref::StableAddress for MetadataBlob {} + +// This is needed so we can create an OwningRef into the blob. +impl std::ops::Deref for MetadataBlob { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + &self.0[..] + } +} // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external @@ -134,6 +153,7 @@ struct ImportedSourceFile { pub(super) struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, cdata: Option>, + blob: &'a MetadataBlob, sess: Option<&'tcx Session>, tcx: Option>, @@ -148,7 +168,11 @@ pub(super) struct DecodeContext<'a, 'tcx> { /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { - fn raw_bytes(self) -> &'a [u8]; + fn blob(self) -> &'a MetadataBlob; + #[inline] + fn raw_bytes(self) -> &'a [u8] { + self.blob() + } fn cdata(self) -> Option> { None } @@ -164,6 +188,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { DecodeContext { opaque: opaque::Decoder::new(self.raw_bytes(), pos), cdata: self.cdata(), + blob: self.blob(), sess: self.sess().or(tcx.map(|tcx| tcx.sess)), tcx, last_source_file_index: 0, @@ -176,17 +201,19 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { } impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { - fn raw_bytes(self) -> &'a [u8] { - &self.0 + #[inline] + fn blob(self) -> &'a MetadataBlob { + self } } impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) { - fn raw_bytes(self) -> &'a [u8] { - let (blob, _) = self; - &blob.0 + #[inline] + fn blob(self) -> &'a MetadataBlob { + self.0 } + #[inline] fn sess(self) -> Option<&'tcx Session> { let (_, sess) = self; Some(sess) @@ -194,33 +221,41 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) { } impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadataRef<'a> { - fn raw_bytes(self) -> &'a [u8] { - self.blob.raw_bytes() + #[inline] + fn blob(self) -> &'a MetadataBlob { + &self.blob } + #[inline] fn cdata(self) -> Option> { Some(*self) } } impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, &'tcx Session) { - fn raw_bytes(self) -> &'a [u8] { - self.0.raw_bytes() + #[inline] + fn blob(self) -> &'a MetadataBlob { + &self.0.blob } + #[inline] fn cdata(self) -> Option> { Some(*self.0) } + #[inline] fn sess(self) -> Option<&'tcx Session> { Some(&self.1) } } impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) { - fn raw_bytes(self) -> &'a [u8] { - self.0.raw_bytes() + #[inline] + fn blob(self) -> &'a MetadataBlob { + &self.0.blob } + #[inline] fn cdata(self) -> Option> { Some(*self.0) } + #[inline] fn tcx(self) -> Option> { Some(self.1) } @@ -246,12 +281,21 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable>> Lazy<[T]> { } impl<'a, 'tcx> DecodeContext<'a, 'tcx> { + #[inline] fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx.expect("missing TyCtxt in DecodeContext") + debug_assert!(self.tcx.is_some(), "missing TyCtxt in DecodeContext"); + self.tcx.unwrap() } - fn cdata(&self) -> CrateMetadataRef<'a> { - self.cdata.expect("missing CrateMetadata in DecodeContext") + #[inline] + pub fn blob(&self) -> &'a MetadataBlob { + self.blob + } + + #[inline] + pub fn cdata(&self) -> CrateMetadataRef<'a> { + debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext"); + self.cdata.unwrap() } fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { @@ -586,7 +630,7 @@ implement_ty_decoder!(DecodeContext<'a, 'tcx>); impl MetadataBlob { crate fn new(metadata_ref: MetadataRef) -> MetadataBlob { - MetadataBlob(metadata_ref) + MetadataBlob(Lrc::new(metadata_ref)) } crate fn is_compatible(&self) -> bool { diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 62c0ce1584594..4dfefda490b3d 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -199,7 +199,7 @@ where debug!("Table::lookup: index={:?} len={:?}", i, self.meta); let start = self.position.get(); - let bytes = &metadata.raw_bytes()[start..start + self.meta]; + let bytes = &metadata.blob()[start..start + self.meta]; >::maybe_read_from_bytes_at(bytes, i.index())? } From d0be27c8ec448e4dd10dfa0f290ffe1bf997de5f Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 20 Jul 2021 13:54:37 +0200 Subject: [PATCH 02/10] Use on-disk-hash-table format for DefPathHashMap in hir::definitions. --- Cargo.lock | 11 ++++++ compiler/rustc_hir/Cargo.toml | 1 + compiler/rustc_hir/src/def_path_hash_map.rs | 37 +++++++++++++++++++++ compiler/rustc_hir/src/definitions.rs | 19 ++++++++--- compiler/rustc_hir/src/lib.rs | 1 + compiler/rustc_metadata/Cargo.toml | 1 + src/tools/tidy/src/deps.rs | 1 + 7 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_hir/src/def_path_hash_map.rs diff --git a/Cargo.lock b/Cargo.lock index cde73166babb7..a03d542139b89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2321,6 +2321,15 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "odht" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e547991b4135151428251dbff22e39ab0f766e0f37cc7d78c5343132be295f" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "once_cell" version = "1.7.2" @@ -3858,6 +3867,7 @@ version = "0.0.0" name = "rustc_hir" version = "0.0.0" dependencies = [ + "odht", "rustc_ast", "rustc_data_structures", "rustc_feature", @@ -4044,6 +4054,7 @@ name = "rustc_metadata" version = "0.0.0" dependencies = [ "libc", + "odht", "rustc_ast", "rustc_attr", "rustc_data_structures", diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index c92551c29307b..ee1b9544e0242 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -17,3 +17,4 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } tracing = "0.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } +odht = { version = "0.1", features = ["nightly"] } diff --git a/compiler/rustc_hir/src/def_path_hash_map.rs b/compiler/rustc_hir/src/def_path_hash_map.rs new file mode 100644 index 0000000000000..8bfb47af26f1a --- /dev/null +++ b/compiler/rustc_hir/src/def_path_hash_map.rs @@ -0,0 +1,37 @@ +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_span::def_id::{DefIndex, DefPathHash}; + +#[derive(Clone, Default)] +pub struct Config; + +impl odht::Config for Config { + type Key = DefPathHash; + type Value = DefIndex; + + type EncodedKey = [u8; 16]; + type EncodedValue = [u8; 4]; + + type H = odht::UnHashFn; + + #[inline] + fn encode_key(k: &DefPathHash) -> [u8; 16] { + k.0.to_le_bytes() + } + + #[inline] + fn encode_value(v: &DefIndex) -> [u8; 4] { + v.as_u32().to_le_bytes() + } + + #[inline] + fn decode_key(k: &[u8; 16]) -> DefPathHash { + DefPathHash(Fingerprint::from_le_bytes(*k)) + } + + #[inline] + fn decode_value(v: &[u8; 4]) -> DefIndex { + DefIndex::from_u32(u32::from_le_bytes(*v)) + } +} + +pub type DefPathHashMap = odht::HashTableOwned; diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 5f56f3a32adde..72a0318479f37 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -6,11 +6,11 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::def_path_hash_map::DefPathHashMap; use crate::hir; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::unhash::UnhashMap; use rustc_index::vec::IndexVec; use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{kw, sym, Symbol}; @@ -28,7 +28,7 @@ use tracing::debug; pub struct DefPathTable { index_to_key: IndexVec, def_path_hashes: IndexVec, - def_path_hash_to_index: UnhashMap, + def_path_hash_to_index: DefPathHashMap, } impl DefPathTable { @@ -44,7 +44,7 @@ impl DefPathTable { // Check for hash collisions of DefPathHashes. These should be // exceedingly rare. - if let Some(existing) = self.def_path_hash_to_index.insert(def_path_hash, index) { + if let Some(existing) = self.def_path_hash_to_index.insert(&def_path_hash, &index) { let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx)); let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx)); @@ -87,7 +87,7 @@ impl DefPathTable { pub fn enumerated_keys_and_path_hashes( &self, - ) -> impl Iterator + '_ { + ) -> impl Iterator + ExactSizeIterator + '_ { self.index_to_key .iter_enumerated() .map(move |(index, key)| (index, key, &self.def_path_hashes[index])) @@ -110,6 +110,9 @@ pub struct Definitions { expansions_that_defined: FxHashMap, def_id_to_span: IndexVec, + + /// The [StableCrateId] of the local crate. + stable_crate_id: StableCrateId, } /// A unique identifier that we can use to lookup a definition @@ -356,6 +359,7 @@ impl Definitions { hir_id_to_def_id: Default::default(), expansions_that_defined: Default::default(), def_id_to_span, + stable_crate_id, } } @@ -440,10 +444,15 @@ impl Definitions { #[inline(always)] pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option { + debug_assert!(hash.stable_crate_id() == self.stable_crate_id); self.table .def_path_hash_to_index .get(&hash) - .map(|&local_def_index| LocalDefId { local_def_index }) + .map(|local_def_index| LocalDefId { local_def_index }) + } + + pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap { + &self.table.def_path_hash_to_index } } diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 42575273839a9..ce36648d6df11 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -16,6 +16,7 @@ extern crate rustc_data_structures; mod arena; pub mod def; +pub mod def_path_hash_map; pub mod definitions; pub use rustc_span::def_id; mod hir; diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 7c79aa5e00bba..b45320c7e8a8e 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -8,6 +8,7 @@ doctest = false [dependencies] libc = "0.2" +odht = { version = "0.1", features = ["nightly"] } snap = "1" tracing = "0.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 5f1267fc3d250..60703384e9e85 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -144,6 +144,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "num-integer", "num-traits", "object", + "odht", "once_cell", "opaque-debug", "parking_lot", From 960893c50a61e6eec6635d8f18b586e3ce0865d9 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 20 Jul 2021 13:59:12 +0200 Subject: [PATCH 03/10] Store DefPathHash->DefIndex map in on-disk-hash-table format in crate metadata. This encoding allows for random access without an expensive upfront decoding state which in turn allows simplifying the DefPathIndex lookup logic without regressing performance. --- compiler/rustc_metadata/src/creader.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 75 ++++------------ .../src/rmeta/decoder/cstore_impl.rs | 16 ++-- .../src/rmeta/def_path_hash_map.rs | 60 +++++++++++++ compiler/rustc_metadata/src/rmeta/encoder.rs | 13 +++ compiler/rustc_metadata/src/rmeta/mod.rs | 4 + compiler/rustc_middle/src/middle/cstore.rs | 8 +- compiler/rustc_middle/src/ty/context.rs | 11 +++ .../rustc_query_impl/src/on_disk_cache.rs | 86 +++---------------- 9 files changed, 131 insertions(+), 144 deletions(-) create mode 100644 compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 99030febb7380..48d8cdf57dcfc 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -45,7 +45,7 @@ pub struct CStore { /// This map is used to verify we get no hash conflicts between /// `StableCrateId` values. - stable_crate_ids: FxHashMap, + pub(crate) stable_crate_ids: FxHashMap, /// Unused externs of the crate unused_externs: Vec, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 06b3ef2add21b..d925e3102f2b7 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -95,10 +95,8 @@ crate struct CrateMetadata { raw_proc_macros: Option<&'static [ProcMacro]>, /// Source maps for code from the crate. source_map_import_info: OnceCell>, - /// For every definition in this crate, maps its `DefPathHash` to its - /// `DefIndex`. See `raw_def_id_to_def_id` for more details about how - /// this is used. - def_path_hash_map: OnceCell>, + /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`. + def_path_hash_map: DefPathHashMap<'static>, /// Likewise for ExpnHash. expn_hash_map: OnceCell>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. @@ -320,6 +318,11 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.lazy_state = LazyState::Previous(NonZeroUsize::new(position + min_size).unwrap()); Ok(Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)) } + + #[inline] + pub fn read_raw_bytes(&mut self, len: usize) -> &'a [u8] { + self.opaque.read_raw_bytes(len) + } } impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { @@ -1596,58 +1599,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self)) } - /// Finds the corresponding `DefId` for the provided `DefPathHash`, if it exists. - /// This is used by incremental compilation to map a serialized `DefPathHash` to - /// its `DefId` in the current session. - /// Normally, only one 'main' crate will change between incremental compilation sessions: - /// all dependencies will be completely unchanged. In this case, we can avoid - /// decoding every `DefPathHash` in the crate, since the `DefIndex` from the previous - /// session will still be valid. If our 'guess' is wrong (the `DefIndex` no longer exists, - /// or has a different `DefPathHash`, then we need to decode all `DefPathHashes` to determine - /// the correct mapping). - fn def_path_hash_to_def_id( - &self, - krate: CrateNum, - index_guess: u32, - hash: DefPathHash, - ) -> Option { - let def_index_guess = DefIndex::from_u32(index_guess); - let old_hash = self - .root - .tables - .def_path_hashes - .get(self, def_index_guess) - .map(|lazy| lazy.decode(self)); - - // Fast path: the definition and its index is unchanged from the - // previous compilation session. There is no need to decode anything - // else - if old_hash == Some(hash) { - return Some(DefId { krate, index: def_index_guess }); - } - - let is_proc_macro = self.is_proc_macro_crate(); - - // Slow path: We need to find out the new `DefIndex` of the provided - // `DefPathHash`, if its still exists. This requires decoding every `DefPathHash` - // stored in this crate. - let map = self.cdata.def_path_hash_map.get_or_init(|| { - let end_id = self.root.tables.def_path_hashes.size() as u32; - let mut map = UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default()); - for i in 0..end_id { - let def_index = DefIndex::from_u32(i); - // There may be gaps in the encoded table if we're decoding a proc-macro crate - if let Some(hash) = self.root.tables.def_path_hashes.get(self, def_index) { - map.insert(hash.decode(self), def_index); - } else if !is_proc_macro { - panic!("Missing def_path_hashes entry for {:?}", def_index); - } - } - map - }); - map.get(&hash).map(|index| DefId { krate, index: *index }) - } - // Returns the path leading to the thing with this `id`. fn def_path(&self, id: DefIndex) -> DefPath { debug!("def_path(cnum={:?}, id={:?})", self.cnum, id); @@ -1670,6 +1621,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.def_path_hash_unlocked(index, &mut def_path_hashes) } + #[inline] + fn def_path_hash_to_def_index(&self, hash: DefPathHash) -> Option { + self.def_path_hash_map.def_path_hash_to_def_index(&hash) + } + fn expn_hash_to_expn_id(&self, index_guess: u32, hash: ExpnHash) -> ExpnId { debug_assert_eq!(ExpnId::from_hash(hash), None); let index_guess = ExpnIndex::from_u32(index_guess); @@ -1936,13 +1892,18 @@ impl CrateMetadata { let alloc_decoding_state = AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); let dependencies = Lock::new(cnum_map.iter().cloned().collect()); + + // Pre-decode the DefPathHash->DefIndex table. This is a cheap operation + // that does not copy any data. It just does some data verification. + let def_path_hash_map = root.def_path_hash_map.decode(&blob); + CrateMetadata { blob, root, trait_impls, raw_proc_macros, source_map_import_info: OnceCell::new(), - def_path_hash_map: Default::default(), + def_path_hash_map, expn_hash_map: Default::default(), alloc_decoding_state, cnum, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index a01eaf68f01c2..4885de103a04a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -498,6 +498,10 @@ impl CrateStore for CStore { self.get_crate_data(cnum).root.stable_crate_id } + fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum { + self.stable_crate_ids[&stable_crate_id] + } + /// Returns the `DefKey` for a given `DefId`. This indicates the /// parent `DefId` as well as some idea of what kind of data the /// `DefId` refers to. @@ -513,14 +517,10 @@ impl CrateStore for CStore { self.get_crate_data(def.krate).def_path_hash(def.index) } - // See `CrateMetadataRef::def_path_hash_to_def_id` for more details - fn def_path_hash_to_def_id( - &self, - cnum: CrateNum, - index_guess: u32, - hash: DefPathHash, - ) -> Option { - self.get_crate_data(cnum).def_path_hash_to_def_id(cnum, index_guess, hash) + fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> Option { + self.get_crate_data(cnum) + .def_path_hash_to_def_index(hash) + .map(|index| DefId { krate: cnum, index }) } fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId { diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs new file mode 100644 index 0000000000000..3f500fce33499 --- /dev/null +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -0,0 +1,60 @@ +use crate::rmeta::DecodeContext; +use crate::rmeta::EncodeContext; +use crate::rmeta::MetadataBlob; +use rustc_data_structures::owning_ref::OwningRef; +use rustc_hir::def_path_hash_map::{ + Config as HashMapConfig, DefPathHashMap as DefPathHashMapInner, +}; +use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; +use rustc_span::def_id::{DefIndex, DefPathHash}; + +crate enum DefPathHashMap<'tcx> { + OwnedFromMetadata(odht::HashTable>), + BorrowedFromTcx(&'tcx DefPathHashMapInner), +} + +impl DefPathHashMap<'tcx> { + #[inline] + pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> Option { + match *self { + DefPathHashMap::OwnedFromMetadata(ref map) => map.get(def_path_hash), + DefPathHashMap::BorrowedFromTcx(_) => { + panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization") + } + } + } +} + +impl<'a, 'tcx> Encodable> for DefPathHashMap<'tcx> { + fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult { + match *self { + DefPathHashMap::BorrowedFromTcx(def_path_hash_map) => { + let bytes = def_path_hash_map.raw_bytes(); + e.emit_usize(bytes.len())?; + e.emit_raw_bytes(bytes) + } + DefPathHashMap::OwnedFromMetadata(_) => { + panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization") + } + } + } +} + +impl<'a, 'tcx> Decodable> for DefPathHashMap<'static> { + fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result, String> { + // Import TyDecoder so we can access the DecodeContext::position() method + use crate::rustc_middle::ty::codec::TyDecoder; + + let len = d.read_usize()?; + let pos = d.position(); + let o = OwningRef::new(d.blob().clone()).map(|x| &x[pos..pos + len]); + + // Although we already have the data we need via the OwningRef, we still need + // to advance the DecodeContext's position so it's in a valid state after + // the method. We use read_raw_bytes() for that. + let _ = d.read_raw_bytes(len); + + let inner = odht::HashTable::from_raw_bytes(o).map_err(|e| format!("{}", e))?; + Ok(DefPathHashMap::OwnedFromMetadata(inner)) + } +} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b0d22037f21a9..5a901e33df945 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1,3 +1,4 @@ +use crate::rmeta::def_path_hash_map::DefPathHashMap; use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; use crate::rmeta::*; @@ -472,6 +473,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } + fn encode_def_path_hash_map(&mut self) -> Lazy> { + self.lazy(DefPathHashMap::BorrowedFromTcx( + self.tcx.resolutions(()).definitions.def_path_hash_to_def_index_map(), + )) + } + fn encode_source_map(&mut self) -> Lazy<[rustc_span::SourceFile]> { let source_map = self.tcx.sess.source_map(); let all_source_files = source_map.files(); @@ -675,6 +682,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene(); let hygiene_bytes = self.position() - i; + i = self.position(); + let def_path_hash_map = self.encode_def_path_hash_map(); + let def_path_hash_map_bytes = self.position() - i; + // Encode source_map. This needs to be done last, // since encoding `Span`s tells us which `SourceFiles` we actually // need to encode. @@ -722,6 +733,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { syntax_contexts, expn_data, expn_hashes, + def_path_hash_map, }); let total_bytes = self.position(); @@ -744,6 +756,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { eprintln!(" impl bytes: {}", impl_bytes); eprintln!(" exp. symbols bytes: {}", exported_symbols_bytes); eprintln!(" def-path table bytes: {}", def_path_table_bytes); + eprintln!(" def-path hashes bytes: {}", def_path_hash_map_bytes); eprintln!(" proc-macro-data-bytes: {}", proc_macro_data_bytes); eprintln!(" mir bytes: {}", mir_bytes); eprintln!(" item bytes: {}", item_bytes); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1f307f3fdeee3..d47537b86ab58 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -1,4 +1,5 @@ use decoder::Metadata; +use def_path_hash_map::DefPathHashMap; use table::{Table, TableBuilder}; use rustc_ast::{self as ast, MacroDef}; @@ -35,6 +36,7 @@ use encoder::EncodeContext; use rustc_span::hygiene::SyntaxContextData; mod decoder; +mod def_path_hash_map; mod encoder; mod table; @@ -231,6 +233,8 @@ crate struct CrateRoot<'tcx> { expn_data: ExpnDataTable, expn_hashes: ExpnHashTable, + def_path_hash_map: Lazy>, + source_map: Lazy<[rustc_span::SourceFile]>, compiler_builtins: bool, diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs index 8150e67929509..b66260c5de36d 100644 --- a/compiler/rustc_middle/src/middle/cstore.rs +++ b/compiler/rustc_middle/src/middle/cstore.rs @@ -199,14 +199,10 @@ pub trait CrateStore: std::fmt::Debug { // incr. comp. uses to identify a CrateNum. fn crate_name(&self, cnum: CrateNum) -> Symbol; fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId; + fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum; /// Fetch a DefId from a DefPathHash for a foreign crate. - fn def_path_hash_to_def_id( - &self, - cnum: CrateNum, - index_guess: u32, - hash: DefPathHash, - ) -> Option; + fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> Option; fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId; // utility functions diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1f5057d1da22f..224a01c4ab663 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1316,6 +1316,17 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Maps a StableCrateId to the corresponding CrateNum. This method assumes + /// that the crate in question has already been loaded by the CrateStore. + #[inline] + pub fn stable_crate_id_to_crate_num(self, stable_crate_id: StableCrateId) -> CrateNum { + if stable_crate_id == self.sess.local_stable_crate_id() { + LOCAL_CRATE + } else { + self.untracked_resolutions.cstore.stable_crate_id_to_crate_num(stable_crate_id) + } + } + pub fn def_path_debug_str(self, def_id: DefId) -> String { // We are explicitly not going through queries here in order to get // crate name and stable crate id since this code is called from debug!() diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index bfd36bfb2db23..ddba6e5ae7aac 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -25,7 +25,6 @@ use rustc_span::hygiene::{ use rustc_span::source_map::{SourceMap, StableSourceFileId}; use rustc_span::CachingSourceMapView; use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span}; -use std::collections::hash_map::Entry; use std::mem; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; @@ -414,79 +413,22 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { } fn def_path_hash_to_def_id(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) -> Option { - let mut cache = self.def_path_hash_to_def_id_cache.lock(); - match cache.entry(hash) { - Entry::Occupied(e) => *e.get(), - Entry::Vacant(e) => { - debug!("def_path_hash_to_def_id({:?})", hash); - // Check if the `DefPathHash` corresponds to a definition in the current - // crate - if let Some(def_id) = - tcx.definitions_untracked().local_def_path_hash_to_def_id(hash) - { - let def_id = def_id.to_def_id(); - e.insert(Some(def_id)); - return Some(def_id); - } - // This `raw_def_id` represents the `DefId` of this `DefPathHash` in - // the *previous* compliation session. The `DefPathHash` includes the - // owning crate, so if the corresponding definition still exists in the - // current compilation session, the crate is guaranteed to be the same - // (otherwise, we would compute a different `DefPathHash`). - let raw_def_id = self.get_raw_def_id(&hash)?; - debug!("def_path_hash_to_def_id({:?}): raw_def_id = {:?}", hash, raw_def_id); - // If the owning crate no longer exists, the corresponding definition definitely - // no longer exists. - let krate = self.try_remap_cnum(tcx, hash.stable_crate_id())?; - debug!("def_path_hash_to_def_id({:?}): krate = {:?}", hash, krate); - // If our `DefPathHash` corresponded to a definition in the local crate, - // we should have either found it in `local_def_path_hash_to_def_id`, or - // never attempted to load it in the first place. Any query result or `DepNode` - // that references a local `DefId` should depend on some HIR-related `DepNode`. - // If a local definition is removed/modified such that its old `DefPathHash` - // no longer has a corresponding definition, that HIR-related `DepNode` should - // end up red. This should prevent us from ever calling - // `tcx.def_path_hash_to_def_id`, since we'll end up recomputing any - // queries involved. - debug_assert_ne!(krate, LOCAL_CRATE); - // Try to find a definition in the current session, using the previous `DefIndex` - // as an initial guess. - let opt_def_id = - tcx.cstore_untracked().def_path_hash_to_def_id(krate, raw_def_id.index, hash); - debug!("def_path_to_def_id({:?}): opt_def_id = {:?}", hash, opt_def_id); - e.insert(opt_def_id); - opt_def_id - } - } - } + debug!("def_path_hash_to_def_id({:?})", hash); - fn register_reused_dep_node(&self, tcx: TyCtxt<'sess>, dep_node: &DepNode) { - // For reused dep nodes, we only need to store the mapping if the node - // is one whose query key we can reconstruct from the hash. We use the - // mapping to aid that reconstruction in the next session. While we also - // use it to decode `DefId`s we encoded in the cache as `DefPathHashes`, - // they're already registered during `DefId` encoding. - if dep_node.kind.can_reconstruct_query_key() { - let hash = DefPathHash(dep_node.hash.into()); - - // We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to - // `latest_foreign_def_path_hashes`, since the `RawDefId` might have - // changed in the current compilation session (e.g. we've added/removed crates, - // or added/removed definitions before/after the target definition). - if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) { - if !def_id.is_local() { - self.store_foreign_def_id_hash(def_id, hash); - } - } - } - } + let stable_crate_id = hash.stable_crate_id(); - fn store_foreign_def_id_hash(&self, def_id: DefId, hash: DefPathHash) { - // We may overwrite an existing entry, but it will have the same value, - // so it's fine - self.latest_foreign_def_path_hashes - .lock() - .insert(hash, RawDefId { krate: def_id.krate.as_u32(), index: def_id.index.as_u32() }); + // If this is a DefPathHash from the local crate, we can look up the + // DefId in the tcx's `Definitions`. + if stable_crate_id == tcx.sess.local_stable_crate_id() { + tcx.definitions_untracked() + .local_def_path_hash_to_def_id(hash) + .map(LocalDefId::to_def_id) + } else { + // If this is a DefPathHash from an upstream crate, let the CrateStore map + // it to a DefId. + let cnum = tcx.cstore_untracked().stable_crate_id_to_crate_num(stable_crate_id); + tcx.cstore_untracked().def_path_hash_to_def_id(cnum, hash) + } } } From 5445715c20dbedbe9b14d185937ab1ebcd81118e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 20 Jul 2021 14:03:20 +0200 Subject: [PATCH 04/10] Remove RawDefId tracking infrastructure from incr. comp. framework. This infrastructure is obsolete now with the new encoding scheme for the DefPathHash->DefIndex maps in crate metadata. --- .../rustc_middle/src/dep_graph/dep_node.rs | 12 +-- compiler/rustc_middle/src/dep_graph/mod.rs | 7 +- compiler/rustc_middle/src/ty/context.rs | 14 +--- .../rustc_query_impl/src/on_disk_cache.rs | 79 +------------------ .../src/dep_graph/dep_node.rs | 12 --- .../rustc_query_system/src/dep_graph/graph.rs | 14 ---- .../rustc_query_system/src/dep_graph/mod.rs | 2 - 7 files changed, 6 insertions(+), 134 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 8476929eaeced..3f28cd51af705 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -385,17 +385,7 @@ impl<'tcx> DepNodeParams> for DefId { } fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { - let hash = tcx.def_path_hash(*self); - // If this is a foreign `DefId`, store its current value - // in the incremental cache. When we decode the cache, - // we will use the old DefIndex as an initial guess for - // a lookup into the crate metadata. - if !self.is_local() { - if let Some(cache) = &tcx.on_disk_cache { - cache.store_foreign_def_id_hash(*self, hash); - } - } - hash.0 + tcx.def_path_hash(*self).0 } fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index aa61219ad789e..35dc1631db3c2 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -92,12 +92,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { type DepKind = DepKind; type StableHashingContext = StableHashingContext<'tcx>; - fn register_reused_dep_node(&self, dep_node: &DepNode) { - if let Some(cache) = self.on_disk_cache.as_ref() { - cache.register_reused_dep_node(*self, dep_node) - } - } - + #[inline] fn create_stable_hashing_context(&self) -> Self::StableHashingContext { TyCtxt::create_stable_hashing_context(*self) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 224a01c4ab663..a13fe75fd4d77 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1,7 +1,7 @@ //! Type context book-keeping. use crate::arena::Arena; -use crate::dep_graph::{DepGraph, DepNode}; +use crate::dep_graph::DepGraph; use crate::hir::place::Place as HirPlace; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; @@ -89,18 +89,6 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { def_path_hash: DefPathHash, ) -> Option; - /// If the given `dep_node`'s hash still exists in the current compilation, - /// and its current `DefId` is foreign, calls `store_foreign_def_id` with it. - /// - /// Normally, `store_foreign_def_id_hash` can be called directly by - /// the dependency graph when we construct a `DepNode`. However, - /// when we re-use a deserialized `DepNode` from the previous compilation - /// session, we only have the `DefPathHash` available. This method is used - /// to that any `DepNode` that we re-use has a `DefPathHash` -> `RawId` written - /// out for usage in the next compilation session. - fn register_reused_dep_node(&self, tcx: TyCtxt<'tcx>, dep_node: &DepNode); - fn store_foreign_def_id_hash(&self, def_id: DefId, hash: DefPathHash); - fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>); fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult; diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index ddba6e5ae7aac..82cc81ec4c3df 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -6,7 +6,7 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathHash; use rustc_index::vec::{Idx, IndexVec}; -use rustc_middle::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; +use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::mir::{self, interpret}; use rustc_middle::thir; @@ -86,27 +86,9 @@ pub struct OnDiskCache<'sess> { expn_data: UnhashMap, // Additional information used when decoding hygiene data. hygiene_context: HygieneDecodeContext, - // Maps `DefPathHash`es to their `RawDefId`s from the *previous* - // compilation session. This is used as an initial 'guess' when - // we try to map a `DefPathHash` to its `DefId` in the current compilation - // session. - foreign_def_path_hashes: UnhashMap, + // FIXME(mw): Update this comment: // Likewise for ExpnId. foreign_expn_data: UnhashMap, - - // The *next* compilation sessison's `foreign_def_path_hashes` - at - // the end of our current compilation session, this will get written - // out to the `foreign_def_path_hashes` field of the `Footer`, which - // will become `foreign_def_path_hashes` of the next compilation session. - // This stores any `DefPathHash` that we may need to map to a `DefId` - // during the next compilation session. - latest_foreign_def_path_hashes: Lock>, - - // Caches all lookups of `DefPathHashes`, both for local and foreign - // definitions. A definition from the previous compilation session - // may no longer exist in the current compilation session, so - // we use `Option` so that we can cache a lookup failure. - def_path_hash_to_def_id_cache: Lock>>, } // This type is used only for serialization and deserialization. @@ -121,7 +103,6 @@ struct Footer { syntax_contexts: FxHashMap, // See `OnDiskCache.expn_data` expn_data: UnhashMap, - foreign_def_path_hashes: UnhashMap, foreign_expn_data: UnhashMap, } @@ -144,19 +125,6 @@ impl AbsoluteBytePos { } } -/// Represents a potentially invalid `DefId`. This is used during incremental -/// compilation to represent a `DefId` from the *previous* compilation session, -/// which may no longer be valid. This is used to help map a `DefPathHash` -/// to a `DefId` in the current compilation session. -#[derive(Encodable, Decodable, Copy, Clone, Debug)] -crate struct RawDefId { - // We deliberately do not use `CrateNum` and `DefIndex` - // here, since a crate/index from the previous compilation - // session may no longer exist. - pub krate: u32, - pub index: u32, -} - /// An `EncodedSourceFileId` is the same as a `StableSourceFileId` except that /// the source crate is represented as a [StableCrateId] instead of as a /// `CrateNum`. This way `EncodedSourceFileId` can be encoded and decoded @@ -220,9 +188,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { expn_data: footer.expn_data, foreign_expn_data: footer.foreign_expn_data, hygiene_context: Default::default(), - foreign_def_path_hashes: footer.foreign_def_path_hashes, - latest_foreign_def_path_hashes: Default::default(), - def_path_hash_to_def_id_cache: Default::default(), } } @@ -241,9 +206,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { expn_data: UnhashMap::default(), foreign_expn_data: UnhashMap::default(), hygiene_context: Default::default(), - foreign_def_path_hashes: Default::default(), - latest_foreign_def_path_hashes: Default::default(), - def_path_hash_to_def_id_cache: Default::default(), } } @@ -253,13 +215,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { /// In order to serialize the new on-disk cache, the former on-disk cache file needs to be /// deleted, hence we won't be able to refer to its memmapped data. fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>) { - // Register any dep nodes that we reused from the previous session, - // but didn't `DepNode::construct` in this session. This ensures - // that their `DefPathHash` to `RawDefId` mappings are registered - // in 'latest_foreign_def_path_hashes' if necessary, since that - // normally happens in `DepNode::construct`. - tcx.dep_graph.register_reused_dep_nodes(tcx); - // Load everything into memory so we can write it out to the on-disk // cache. The vast majority of cacheable query results should already // be in memory, so this should be a cheap operation. @@ -293,7 +248,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { (file_to_file_index, file_index_to_stable_id) }; - let latest_foreign_def_path_hashes = self.latest_foreign_def_path_hashes.lock().clone(); let hygiene_encode_context = HygieneEncodeContext::default(); let mut encoder = CacheEncoder { @@ -305,7 +259,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { source_map: CachingSourceMapView::new(tcx.sess.source_map()), file_to_file_index, hygiene_context: &hygiene_encode_context, - latest_foreign_def_path_hashes, }; // Encode query results. @@ -382,9 +335,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { }, )?; - let foreign_def_path_hashes = - std::mem::take(&mut encoder.latest_foreign_def_path_hashes); - // `Encode the file footer. let footer_pos = encoder.position() as u64; encoder.encode_tagged( @@ -397,7 +347,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { syntax_contexts, expn_data, foreign_expn_data, - foreign_def_path_hashes, }, )?; @@ -460,17 +409,6 @@ impl<'sess> OnDiskCache<'sess> { debug_assert!(prev.is_none()); } - fn get_raw_def_id(&self, hash: &DefPathHash) -> Option { - self.foreign_def_path_hashes.get(hash).copied() - } - - fn try_remap_cnum(&self, tcx: TyCtxt<'_>, stable_crate_id: StableCrateId) -> Option { - let cnum_map = self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx)); - debug!("try_remap_cnum({:?}): cnum_map={:?}", stable_crate_id, cnum_map); - - cnum_map.get(&stable_crate_id).copied() - } - /// Returns the cached query result if there is something in the cache for /// the given `SerializedDepNodeIndex`; otherwise returns `None`. pub fn try_load_query_result<'tcx, T>( @@ -911,7 +849,6 @@ pub struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> { source_map: CachingSourceMapView<'tcx>, file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>, hygiene_context: &'a HygieneEncodeContext, - latest_foreign_def_path_hashes: UnhashMap, } impl<'a, 'tcx, E> CacheEncoder<'a, 'tcx, E> @@ -1044,17 +981,7 @@ where E: 'a + OpaqueEncoder, { fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) -> Result<(), E::Error> { - let def_path_hash = s.tcx.def_path_hash(*self); - // Store additional information when we encode a foreign `DefId`, - // so that we can map its `DefPathHash` back to a `DefId` in the next - // compilation session. - if !self.is_local() { - s.latest_foreign_def_path_hashes.insert( - def_path_hash, - RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() }, - ); - } - def_path_hash.encode(s) + s.tcx.def_path_hash(*self).encode(s) } } diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 59ef6052a60c0..46dc0c720ce7f 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -53,18 +53,6 @@ use std::hash::Hash; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] pub struct DepNode { pub kind: K, - // Important - whenever a `DepNode` is constructed, we need to make - // sure to register a `DefPathHash -> DefId` mapping if needed. - // This is currently done in two places: - // - // * When a `DepNode::construct` is called, `arg.to_fingerprint()` - // is responsible for calling `OnDiskCache::store_foreign_def_id_hash` - // if needed - // * When we serialize the on-disk cache, `OnDiskCache::serialize` is - // responsible for calling `DepGraph::register_reused_dep_nodes`. - // - // FIXME: Enforce this by preventing manual construction of `DefNode` - // (e.g. add a `_priv: ()` field) pub hash: PackedFingerprint, } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index e589d16992f6c..23a4377184272 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -760,20 +760,6 @@ impl DepGraph { } } - // Register reused dep nodes (i.e. nodes we've marked red or green) with the context. - pub fn register_reused_dep_nodes>(&self, tcx: Ctxt) { - let data = self.data.as_ref().unwrap(); - for prev_index in data.colors.values.indices() { - match data.colors.get(prev_index) { - Some(DepNodeColor::Red) | Some(DepNodeColor::Green(_)) => { - let dep_node = data.previous.index_to_node(prev_index); - tcx.register_reused_dep_node(&dep_node); - } - None => {} - } - } - } - pub fn print_incremental_info(&self) { if let Some(data) = &self.data { data.current.encoder.borrow().print_incremental_info( diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 15e2633c4f12e..b5be1192ce73f 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -27,8 +27,6 @@ pub trait DepContext: Copy { /// Access the DepGraph. fn dep_graph(&self) -> &DepGraph; - fn register_reused_dep_node(&self, dep_node: &DepNode); - /// Access the profiler. fn profiler(&self) -> &SelfProfilerRef; From 2b60338ee92fbae7e9414dd1bd6661ccd8a7b9da Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 20 Jul 2021 14:18:37 +0200 Subject: [PATCH 05/10] Make DefPathHash->DefId panic for if the mapping fails. We only use this mapping for cases where we know that it must succeed. Letting it panic otherwise makes it harder to use the API in unsupported ways. --- compiler/rustc_hir/src/definitions.rs | 3 ++- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 7 +++---- .../rustc_metadata/src/rmeta/def_path_hash_map.rs | 4 ++-- compiler/rustc_middle/src/dep_graph/dep_node.rs | 6 +++++- compiler/rustc_middle/src/middle/cstore.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 6 +----- compiler/rustc_query_impl/src/on_disk_cache.rs | 13 +++---------- 8 files changed, 18 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 72a0318479f37..ca29351455e62 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -443,12 +443,13 @@ impl Definitions { } #[inline(always)] - pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option { + pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> LocalDefId { debug_assert!(hash.stable_crate_id() == self.stable_crate_id); self.table .def_path_hash_to_index .get(&hash) .map(|local_def_index| LocalDefId { local_def_index }) + .unwrap() } pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index d925e3102f2b7..51a8dcc9db4ad 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1622,7 +1622,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } #[inline] - fn def_path_hash_to_def_index(&self, hash: DefPathHash) -> Option { + fn def_path_hash_to_def_index(&self, hash: DefPathHash) -> DefIndex { self.def_path_hash_map.def_path_hash_to_def_index(&hash) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4885de103a04a..70952d388d52d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -517,10 +517,9 @@ impl CrateStore for CStore { self.get_crate_data(def.krate).def_path_hash(def.index) } - fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> Option { - self.get_crate_data(cnum) - .def_path_hash_to_def_index(hash) - .map(|index| DefId { krate: cnum, index }) + fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId { + let def_index = self.get_crate_data(cnum).def_path_hash_to_def_index(hash); + DefId { krate: cnum, index: def_index } } fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId { diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 3f500fce33499..e2095d553f535 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -15,9 +15,9 @@ crate enum DefPathHashMap<'tcx> { impl DefPathHashMap<'tcx> { #[inline] - pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> Option { + pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex { match *self { - DefPathHashMap::OwnedFromMetadata(ref map) => map.get(def_path_hash), + DefPathHashMap::OwnedFromMetadata(ref map) => map.get(def_path_hash).unwrap(), DefPathHashMap::BorrowedFromTcx(_) => { panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization") } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 3f28cd51af705..e788dd4be85d7 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -336,7 +336,11 @@ impl DepNodeExt for DepNode { /// has been removed. fn extract_def_id(&self, tcx: TyCtxt<'tcx>) -> Option { if self.kind.can_reconstruct_query_key() { - tcx.on_disk_cache.as_ref()?.def_path_hash_to_def_id(tcx, DefPathHash(self.hash.into())) + Some( + tcx.on_disk_cache + .as_ref()? + .def_path_hash_to_def_id(tcx, DefPathHash(self.hash.into())), + ) } else { None } diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs index b66260c5de36d..81c44b27033ec 100644 --- a/compiler/rustc_middle/src/middle/cstore.rs +++ b/compiler/rustc_middle/src/middle/cstore.rs @@ -202,7 +202,7 @@ pub trait CrateStore: std::fmt::Debug { fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum; /// Fetch a DefId from a DefPathHash for a foreign crate. - fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> Option; + fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId; fn expn_hash_to_expn_id(&self, cnum: CrateNum, index_guess: u32, hash: ExpnHash) -> ExpnId; // utility functions diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a13fe75fd4d77..706c395943335 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -83,11 +83,7 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation /// session, if it still exists. This is used during incremental compilation to /// turn a deserialized `DefPathHash` into its current `DefId`. - fn def_path_hash_to_def_id( - &self, - tcx: TyCtxt<'tcx>, - def_path_hash: DefPathHash, - ) -> Option; + fn def_path_hash_to_def_id(&self, tcx: TyCtxt<'tcx>, def_path_hash: DefPathHash) -> DefId; fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>); diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 82cc81ec4c3df..f9456a6f2cdb8 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -361,7 +361,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { }) } - fn def_path_hash_to_def_id(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) -> Option { + fn def_path_hash_to_def_id(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) -> DefId { debug!("def_path_hash_to_def_id({:?})", hash); let stable_crate_id = hash.stable_crate_id(); @@ -369,9 +369,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { // If this is a DefPathHash from the local crate, we can look up the // DefId in the tcx's `Definitions`. if stable_crate_id == tcx.sess.local_stable_crate_id() { - tcx.definitions_untracked() - .local_def_path_hash_to_def_id(hash) - .map(LocalDefId::to_def_id) + tcx.definitions_untracked().local_def_path_hash_to_def_id(hash).to_def_id() } else { // If this is a DefPathHash from an upstream crate, let the CrateStore map // it to a DefId. @@ -779,12 +777,7 @@ impl<'a, 'tcx> Decodable> for DefId { // If we get to this point, then all of the query inputs were green, // which means that the definition with this hash is guaranteed to // still exist in the current compilation session. - Ok(d.tcx() - .on_disk_cache - .as_ref() - .unwrap() - .def_path_hash_to_def_id(d.tcx(), def_path_hash) - .unwrap()) + Ok(d.tcx().on_disk_cache.as_ref().unwrap().def_path_hash_to_def_id(d.tcx(), def_path_hash)) } } From 021c0520e3ec4ddecac425f99db5749942785e65 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 21 Jul 2021 13:38:29 +0200 Subject: [PATCH 06/10] Fix up comment about OnDiskCache::foreign_expn_data. --- compiler/rustc_query_impl/src/on_disk_cache.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index f9456a6f2cdb8..cb50c851e9a45 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -86,8 +86,10 @@ pub struct OnDiskCache<'sess> { expn_data: UnhashMap, // Additional information used when decoding hygiene data. hygiene_context: HygieneDecodeContext, - // FIXME(mw): Update this comment: - // Likewise for ExpnId. + // Maps `ExpnHash`es to their raw value from the *previous* + // compilation session. This is used as an initial 'guess' when + // we try to map an `ExpnHash` to its value in the current + // compilation session. foreign_expn_data: UnhashMap, } From 5f73085f925cd008fc28eed302f8bc026e7fb71c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 18 Aug 2021 18:29:11 +0200 Subject: [PATCH 07/10] Rename DefPathHashMap in rustc_metadata so its name does not clash with DefPathHashMap in rustc_hir. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 +-- .../src/rmeta/def_path_hash_map.rs | 26 +++++++++---------- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 ++--- compiler/rustc_metadata/src/rmeta/mod.rs | 4 +-- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 51a8dcc9db4ad..8bb36103cd099 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -55,7 +55,7 @@ mod cstore_impl; crate struct MetadataBlob(Lrc); // This is needed so we can create an OwningRef into the blob. -// The data behind a `MetadataBlob` has a stable address because it +// The data behind a `MetadataBlob` has a stable address because it is // contained within an Rc/Arc. unsafe impl rustc_data_structures::owning_ref::StableAddress for MetadataBlob {} @@ -96,7 +96,7 @@ crate struct CrateMetadata { /// Source maps for code from the crate. source_map_import_info: OnceCell>, /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`. - def_path_hash_map: DefPathHashMap<'static>, + def_path_hash_map: DefPathHashMapRef<'static>, /// Likewise for ExpnHash. expn_hash_map: OnceCell>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index e2095d553f535..d6435bb649d6d 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -2,46 +2,44 @@ use crate::rmeta::DecodeContext; use crate::rmeta::EncodeContext; use crate::rmeta::MetadataBlob; use rustc_data_structures::owning_ref::OwningRef; -use rustc_hir::def_path_hash_map::{ - Config as HashMapConfig, DefPathHashMap as DefPathHashMapInner, -}; +use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap}; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use rustc_span::def_id::{DefIndex, DefPathHash}; -crate enum DefPathHashMap<'tcx> { +crate enum DefPathHashMapRef<'tcx> { OwnedFromMetadata(odht::HashTable>), - BorrowedFromTcx(&'tcx DefPathHashMapInner), + BorrowedFromTcx(&'tcx DefPathHashMap), } -impl DefPathHashMap<'tcx> { +impl DefPathHashMapRef<'tcx> { #[inline] pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex { match *self { - DefPathHashMap::OwnedFromMetadata(ref map) => map.get(def_path_hash).unwrap(), - DefPathHashMap::BorrowedFromTcx(_) => { + DefPathHashMapRef::OwnedFromMetadata(ref map) => map.get(def_path_hash).unwrap(), + DefPathHashMapRef::BorrowedFromTcx(_) => { panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization") } } } } -impl<'a, 'tcx> Encodable> for DefPathHashMap<'tcx> { +impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult { match *self { - DefPathHashMap::BorrowedFromTcx(def_path_hash_map) => { + DefPathHashMapRef::BorrowedFromTcx(def_path_hash_map) => { let bytes = def_path_hash_map.raw_bytes(); e.emit_usize(bytes.len())?; e.emit_raw_bytes(bytes) } - DefPathHashMap::OwnedFromMetadata(_) => { + DefPathHashMapRef::OwnedFromMetadata(_) => { panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization") } } } } -impl<'a, 'tcx> Decodable> for DefPathHashMap<'static> { - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result, String> { +impl<'a, 'tcx> Decodable> for DefPathHashMapRef<'static> { + fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result, String> { // Import TyDecoder so we can access the DecodeContext::position() method use crate::rustc_middle::ty::codec::TyDecoder; @@ -55,6 +53,6 @@ impl<'a, 'tcx> Decodable> for DefPathHashMap<'static> { let _ = d.read_raw_bytes(len); let inner = odht::HashTable::from_raw_bytes(o).map_err(|e| format!("{}", e))?; - Ok(DefPathHashMap::OwnedFromMetadata(inner)) + Ok(DefPathHashMapRef::OwnedFromMetadata(inner)) } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 5a901e33df945..a50c4549d3d3f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1,4 +1,4 @@ -use crate::rmeta::def_path_hash_map::DefPathHashMap; +use crate::rmeta::def_path_hash_map::DefPathHashMapRef; use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; use crate::rmeta::*; @@ -473,8 +473,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - fn encode_def_path_hash_map(&mut self) -> Lazy> { - self.lazy(DefPathHashMap::BorrowedFromTcx( + fn encode_def_path_hash_map(&mut self) -> Lazy> { + self.lazy(DefPathHashMapRef::BorrowedFromTcx( self.tcx.resolutions(()).definitions.def_path_hash_to_def_index_map(), )) } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index d47537b86ab58..eb2bd80f46e64 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -1,5 +1,5 @@ use decoder::Metadata; -use def_path_hash_map::DefPathHashMap; +use def_path_hash_map::DefPathHashMapRef; use table::{Table, TableBuilder}; use rustc_ast::{self as ast, MacroDef}; @@ -233,7 +233,7 @@ crate struct CrateRoot<'tcx> { expn_data: ExpnDataTable, expn_hashes: ExpnHashTable, - def_path_hash_map: Lazy>, + def_path_hash_map: Lazy>, source_map: Lazy<[rustc_span::SourceFile]>, From 919497cc30c076560830a391b558899f3c3e67f3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 24 Aug 2021 14:39:38 +0200 Subject: [PATCH 08/10] rustc_metadata: Remove Metadata::raw_bytes() and use Metadata::blob() directly instead. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8bb36103cd099..eb3a9f576a735 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -167,10 +167,7 @@ pub(super) struct DecodeContext<'a, 'tcx> { /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { fn blob(self) -> &'a MetadataBlob; - #[inline] - fn raw_bytes(self) -> &'a [u8] { - self.blob() - } + fn cdata(self) -> Option> { None } @@ -184,7 +181,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> { let tcx = self.tcx(); DecodeContext { - opaque: opaque::Decoder::new(self.raw_bytes(), pos), + opaque: opaque::Decoder::new(self.blob(), pos), cdata: self.cdata(), blob: self.blob(), sess: self.sess().or(tcx.map(|tcx| tcx.sess)), @@ -637,7 +634,7 @@ impl MetadataBlob { } crate fn is_compatible(&self) -> bool { - self.raw_bytes().starts_with(METADATA_HEADER) + self.blob().starts_with(METADATA_HEADER) } crate fn get_rustc_version(&self) -> String { @@ -646,7 +643,7 @@ impl MetadataBlob { } crate fn get_root(&self) -> CrateRoot<'tcx> { - let slice = self.raw_bytes(); + let slice = &self.blob()[..]; let offset = METADATA_HEADER.len(); let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) From 66cf8ea1afb099c4a18bf9a1526f499aeb4479b6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 8 Sep 2021 18:27:06 +0200 Subject: [PATCH 09/10] Replace cnum_map with tcx.stable_crate_id_to_crate_num() in OnDiskCache. --- .../rustc_query_impl/src/on_disk_cache.rs | 39 ++++--------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index cb50c851e9a45..d8cff0bd1880f 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -1,7 +1,7 @@ use crate::QueryCtxt; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; -use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell, RwLock}; +use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathHash; @@ -50,8 +50,6 @@ pub struct OnDiskCache<'sess> { // session. current_side_effects: Lock>, - cnum_map: OnceCell>, - source_map: &'sess SourceMap, file_index_to_stable_id: FxHashMap, @@ -139,8 +137,8 @@ struct EncodedSourceFileId { } impl EncodedSourceFileId { - fn translate(&self, cnum_map: &UnhashMap) -> StableSourceFileId { - let cnum = cnum_map[&self.stable_crate_id]; + fn translate(&self, tcx: TyCtxt<'_>) -> StableSourceFileId { + let cnum = tcx.stable_crate_id_to_crate_num(self.stable_crate_id); StableSourceFileId { file_name_hash: self.file_name_hash, cnum } } @@ -180,7 +178,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { serialized_data: RwLock::new(Some(data)), file_index_to_stable_id: footer.file_index_to_stable_id, file_index_to_file: Default::default(), - cnum_map: OnceCell::new(), source_map: sess.source_map(), current_side_effects: Default::default(), query_result_index: footer.query_result_index.into_iter().collect(), @@ -198,7 +195,6 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { serialized_data: RwLock::new(None), file_index_to_stable_id: Default::default(), file_index_to_file: Default::default(), - cnum_map: OnceCell::new(), source_map, current_side_effects: Default::default(), query_result_index: Default::default(), @@ -466,14 +462,11 @@ impl<'sess> OnDiskCache<'sess> { where T: Decodable>, { - let cnum_map = self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx)); - let serialized_data = self.serialized_data.read(); let mut decoder = CacheDecoder { tcx, opaque: opaque::Decoder::new(serialized_data.as_deref().unwrap_or(&[]), pos.to_usize()), source_map: self.source_map, - cnum_map, file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(), @@ -484,23 +477,6 @@ impl<'sess> OnDiskCache<'sess> { }; f(&mut decoder) } - - // This function builds mapping from previous-session-`CrateNum` to - // current-session-`CrateNum`. There might be `CrateNum`s from the previous - // `Session` that don't occur in the current one. For these, the mapping - // maps to None. - fn compute_cnum_map(tcx: TyCtxt<'_>) -> UnhashMap { - tcx.dep_graph.with_ignore(|| { - tcx.crates(()) - .iter() - .chain(std::iter::once(&LOCAL_CRATE)) - .map(|&cnum| { - let hash = tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); - (hash, cnum) - }) - .collect() - }) - } } //- DECODING ------------------------------------------------------------------- @@ -512,7 +488,6 @@ pub struct CacheDecoder<'a, 'tcx> { tcx: TyCtxt<'tcx>, opaque: opaque::Decoder<'a>, source_map: &'a SourceMap, - cnum_map: &'a UnhashMap, file_index_to_file: &'a Lock>>, file_index_to_stable_id: &'a FxHashMap, alloc_decoding_session: AllocDecodingSession<'a>, @@ -525,10 +500,10 @@ pub struct CacheDecoder<'a, 'tcx> { impl<'a, 'tcx> CacheDecoder<'a, 'tcx> { fn file_index_to_file(&self, index: SourceFileIndex) -> Lrc { let CacheDecoder { + tcx, ref file_index_to_file, ref file_index_to_stable_id, ref source_map, - ref cnum_map, .. } = *self; @@ -536,7 +511,7 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> { .borrow_mut() .entry(index) .or_insert_with(|| { - let stable_id = file_index_to_stable_id[&index].translate(cnum_map); + let stable_id = file_index_to_stable_id[&index].translate(tcx); source_map .source_file_by_stable_id(stable_id) .expect("failed to lookup `SourceFile` in new context") @@ -678,7 +653,7 @@ impl<'a, 'tcx> Decodable> for ExpnId { return Ok(expn_id); } - let krate = decoder.cnum_map[&hash.stable_crate_id()]; + let krate = decoder.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id()); let expn_id = if krate == LOCAL_CRATE { // We look up the position of the associated `ExpnData` and decode it. @@ -751,7 +726,7 @@ impl<'a, 'tcx> Decodable> for Span { impl<'a, 'tcx> Decodable> for CrateNum { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result { let stable_id = StableCrateId::decode(d)?; - let cnum = d.cnum_map[&stable_id]; + let cnum = d.tcx.stable_crate_id_to_crate_num(stable_id); Ok(cnum) } } From 4d151d92deaf86280b4c96cdc7c6f1a58927bd00 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 10 Sep 2021 14:12:30 +0200 Subject: [PATCH 10/10] Update odht to 0.2.1 --- Cargo.lock | 4 ++-- compiler/rustc_hir/Cargo.toml | 2 +- compiler/rustc_metadata/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a03d542139b89..e3c5340af358a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2323,9 +2323,9 @@ dependencies = [ [[package]] name = "odht" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e547991b4135151428251dbff22e39ab0f766e0f37cc7d78c5343132be295f" +checksum = "0b18a8d1c919d3e7b5c49708d08ef7d60bc2150a7c3a8244257c54ca3f625010" dependencies = [ "cfg-if 1.0.0", ] diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index ee1b9544e0242..ff6758e66dff2 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -17,4 +17,4 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } tracing = "0.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } -odht = { version = "0.1", features = ["nightly"] } +odht = { version = "0.2.1", features = ["nightly"] } diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index b45320c7e8a8e..42596f3318d6c 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -8,7 +8,7 @@ doctest = false [dependencies] libc = "0.2" -odht = { version = "0.1", features = ["nightly"] } +odht = { version = "0.2.1", features = ["nightly"] } snap = "1" tracing = "0.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }