From 5be514992fdeddbf56bb44c7baec3ab5e4f79e1b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 30 May 2021 17:54:49 +0200 Subject: [PATCH] Encode CrateNum using the StableCrateId for incr. comp. --- compiler/rustc_metadata/src/rmeta/decoder.rs | 8 +- compiler/rustc_middle/src/ty/codec.rs | 4 +- .../src/ty/query/on_disk_cache.rs | 101 +++++++----------- 3 files changed, 42 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 52cb1e1996e38..48900fecd3e1b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -252,6 +252,10 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.cdata.expect("missing CrateMetadata in DecodeContext") } + fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { + if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] } + } + fn read_lazy_with_meta( &mut self, meta: T::Meta, @@ -324,10 +328,6 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { r } - fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] } - } - fn decode_alloc_id(&mut self) -> Result { if let Some(alloc_decoding_session) = self.alloc_decoding_session { alloc_decoding_session.decode_alloc_id(self) diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index d7767dc39cb32..5ec665e913cc5 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -15,7 +15,7 @@ use crate::mir::{ use crate::ty::subst::SubstsRef; use crate::ty::{self, List, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_hir::def_id::DefId; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::Span; use std::hash::Hash; @@ -179,8 +179,6 @@ pub trait TyDecoder<'tcx>: Decoder { where F: FnOnce(&mut Self) -> R; - fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum; - fn positioned_at_shorthand(&self) -> bool { (self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0 } diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index 5c42625306bf3..a74a40102a80d 100644 --- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs @@ -9,7 +9,7 @@ use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell}; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unhash::UnhashMap; use rustc_errors::Diagnostic; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; +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_query_system::dep_graph::DepContext; @@ -18,7 +18,7 @@ use rustc_serialize::{ opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize}, Decodable, Decoder, Encodable, Encoder, }; -use rustc_session::{CrateDisambiguator, Session}; +use rustc_session::Session; use rustc_span::hygiene::{ ExpnDataDecodeMode, ExpnDataEncodeMode, ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData, @@ -51,8 +51,7 @@ pub struct OnDiskCache<'sess> { // session. current_diagnostics: Lock>>, - prev_cnums: Vec<(u32, String, CrateDisambiguator)>, - cnum_map: OnceCell>>, + cnum_map: OnceCell>, source_map: &'sess SourceMap, file_index_to_stable_id: FxHashMap, @@ -113,7 +112,6 @@ pub struct OnDiskCache<'sess> { #[derive(Encodable, Decodable)] struct Footer { file_index_to_stable_id: FxHashMap, - prev_cnums: Vec<(u32, String, CrateDisambiguator)>, query_result_index: EncodedQueryResultIndex, diagnostics_index: EncodedQueryResultIndex, // The location of all allocations. @@ -186,7 +184,6 @@ impl<'sess> OnDiskCache<'sess> { serialized_data: data, file_index_to_stable_id: footer.file_index_to_stable_id, file_index_to_file: Default::default(), - prev_cnums: footer.prev_cnums, cnum_map: OnceCell::new(), source_map: sess.source_map(), current_diagnostics: Default::default(), @@ -207,7 +204,6 @@ impl<'sess> OnDiskCache<'sess> { serialized_data: Vec::new(), file_index_to_stable_id: Default::default(), file_index_to_file: Default::default(), - prev_cnums: vec![], cnum_map: OnceCell::new(), source_map, current_diagnostics: Default::default(), @@ -327,16 +323,6 @@ impl<'sess> OnDiskCache<'sess> { interpret_alloc_index }; - let sorted_cnums = sorted_cnums_including_local_crate(tcx); - let prev_cnums: Vec<_> = sorted_cnums - .iter() - .map(|&cnum| { - let crate_name = tcx.crate_name(cnum).to_string(); - let crate_disambiguator = tcx.crate_disambiguator(cnum); - (cnum.as_u32(), crate_name, crate_disambiguator) - }) - .collect(); - let mut syntax_contexts = FxHashMap::default(); let mut expn_ids = FxHashMap::default(); @@ -368,7 +354,6 @@ impl<'sess> OnDiskCache<'sess> { TAG_FILE_FOOTER, &Footer { file_index_to_stable_id, - prev_cnums, query_result_index, diagnostics_index, interpret_alloc_index, @@ -385,16 +370,7 @@ impl<'sess> OnDiskCache<'sess> { // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address // of the footer must be the last thing in the data stream. - return Ok(()); - - fn sorted_cnums_including_local_crate(tcx: TyCtxt<'_>) -> Vec { - let mut cnums = vec![LOCAL_CRATE]; - cnums.extend_from_slice(tcx.crates()); - cnums.sort_unstable(); - // Just to be sure... - cnums.dedup(); - cnums - } + Ok(()) }) } @@ -429,12 +405,11 @@ impl<'sess> OnDiskCache<'sess> { self.foreign_def_path_hashes.get(hash).copied() } - fn try_remap_cnum(&self, tcx: TyCtxt<'_>, cnum: u32) -> Option { - let cnum_map = - self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..])); - debug!("try_remap_cnum({}): cnum_map={:?}", cnum, cnum_map); + 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[CrateNum::from_u32(cnum)] + cnum_map.get(&stable_crate_id).copied() } pub(crate) fn store_foreign_def_id_hash(&self, def_id: DefId, hash: DefPathHash) { @@ -533,8 +508,7 @@ impl<'sess> OnDiskCache<'sess> { where T: Decodable>, { - let cnum_map = - self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..])); + let cnum_map = self.cnum_map.get_or_init(|| Self::compute_cnum_map(tcx)); let mut decoder = CacheDecoder { tcx, @@ -555,31 +529,16 @@ impl<'sess> OnDiskCache<'sess> { // 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<'_>, - prev_cnums: &[(u32, String, CrateDisambiguator)], - ) -> IndexVec> { + fn compute_cnum_map(tcx: TyCtxt<'_>) -> UnhashMap { tcx.dep_graph.with_ignore(|| { - let current_cnums = tcx - .all_crate_nums(()) + tcx.all_crate_nums(()) .iter() + .chain(std::iter::once(&LOCAL_CRATE)) .map(|&cnum| { - let crate_name = tcx.crate_name(cnum).to_string(); - let crate_disambiguator = tcx.crate_disambiguator(cnum); - ((crate_name, crate_disambiguator), cnum) + let hash = tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); + (hash, cnum) }) - .collect::>(); - - let map_size = prev_cnums.iter().map(|&(cnum, ..)| cnum).max().unwrap_or(0) + 1; - let mut map = IndexVec::from_elem_n(None, map_size as usize); - - for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums { - let key = (crate_name.clone(), crate_disambiguator); - map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned(); - } - - map[LOCAL_CRATE] = Some(LOCAL_CRATE); - map + .collect() }) } @@ -612,7 +571,7 @@ impl<'sess> OnDiskCache<'sess> { 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, raw_def_id.krate)?; + 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 @@ -644,7 +603,7 @@ pub struct CacheDecoder<'a, 'tcx> { tcx: TyCtxt<'tcx>, opaque: opaque::Decoder<'a>, source_map: &'a SourceMap, - cnum_map: &'a IndexVec>, + cnum_map: &'a UnhashMap, file_index_to_file: &'a Lock>>, file_index_to_stable_id: &'a FxHashMap, alloc_decoding_session: AllocDecodingSession<'a>, @@ -765,10 +724,6 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { r } - fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - self.cnum_map[cnum].unwrap_or_else(|| bug!("could not find new `CrateNum` for {:?}", cnum)) - } - fn decode_alloc_id(&mut self) -> Result { let alloc_decoding_session = self.alloc_decoding_session; alloc_decoding_session.decode_alloc_id(self) @@ -850,8 +805,9 @@ impl<'a, 'tcx> Decodable> for Span { impl<'a, 'tcx> Decodable> for CrateNum { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result { - let cnum = CrateNum::from_u32(u32::decode(d)?); - Ok(d.map_encoded_cnum_to_current(cnum)) + let stable_id = StableCrateId::decode(d)?; + let cnum = d.cnum_map[&stable_id]; + Ok(cnum) } } @@ -1061,6 +1017,23 @@ where } } +impl<'a, 'tcx, E> Encodable> for CrateNum +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.as_def_id()); + // 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 != LOCAL_CRATE { + s.latest_foreign_def_path_hashes + .insert(def_path_hash, RawDefId { krate: self.as_u32(), index: 0 }); + } + def_path_hash.stable_crate_id().encode(s) + } +} + impl<'a, 'tcx, E> Encodable> for DefId where E: 'a + OpaqueEncoder,