diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/table.rs | 28 |
4 files changed, 77 insertions, 10 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 7b500f1565d..3933a0d19a4 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -388,6 +388,17 @@ impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DeprecationEntry>> } } +impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DefId>> for Option<RawDefId> { + fn decode_query( + self, + cdata: CrateMetadataRef<'a>, + _: TyCtxt<'tcx>, + _: impl FnOnce() -> !, + ) -> Option<DefId> { + self.map(|raw_def_id| raw_def_id.decode(cdata)) + } +} + impl<'a, 'tcx> DecodeContext<'a, 'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { @@ -406,8 +417,9 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.cdata.unwrap() } + #[inline] fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] } + self.cdata().map_encoded_cnum_to_current(cnum) } fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> { @@ -718,8 +730,7 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a } } -impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>> - for Lazy<Table<I, T>> +impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for Lazy<Table<I, T>> where Option<T>: FixedSizeEncoding, { @@ -856,6 +867,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.tables.kind.get(self, item_id).map(|k| k.decode(self)) } + #[inline] + pub(super) fn map_encoded_cnum_to_current(self, cnum: CrateNum) -> CrateNum { + if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] } + } + fn kind(self, item_id: DefIndex) -> EntryKind { self.maybe_kind(item_id).unwrap_or_else(|| { bug!( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index be10ad490e1..e967750aebb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -147,8 +147,7 @@ impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a } } -impl<'a, 'tcx, I: Idx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>> - for Lazy<Table<I, T>> +impl<'a, 'tcx, I: Idx, T> Encodable<EncodeContext<'a, 'tcx>> for Lazy<Table<I, T>> where Option<T>: FixedSizeEncoding, { @@ -1285,7 +1284,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_ident_span(def_id, impl_item.ident(self.tcx)); self.encode_item_type(def_id); if let Some(trait_item_def_id) = impl_item.trait_item_def_id { - record!(self.tables.trait_item_def_id[def_id] <- trait_item_def_id); + self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into()); } if impl_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); @@ -1457,7 +1456,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let trait_def = self.tcx.trait_def(trait_ref.def_id); if let Some(mut an) = trait_def.ancestors(self.tcx, def_id).ok() { if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) { - record!(self.tables.impl_parent[def_id] <- parent); + self.tables.impl_parent.set(def_id.index, parent.into()); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 37340ee3268..43ccfc64e05 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -1,3 +1,4 @@ +use crate::creader::CrateMetadataRef; use decoder::Metadata; use def_path_hash_map::DefPathHashMapRef; use table::{Table, TableBuilder}; @@ -8,7 +9,7 @@ use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; -use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId}; +use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}; use rustc_hir::definitions::DefKey; use rustc_hir::lang_items; use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; @@ -237,6 +238,29 @@ crate struct CrateRoot<'tcx> { symbol_mangling_version: SymbolManglingVersion, } +/// On-disk representation of `DefId`. +/// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk +/// representation and the compilation session. +#[derive(Copy, Clone)] +crate struct RawDefId { + krate: u32, + index: u32, +} + +impl Into<RawDefId> for DefId { + fn into(self) -> RawDefId { + RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() } + } +} + +impl RawDefId { + fn decode(self, cdata: CrateMetadataRef<'_>) -> DefId { + let krate = CrateNum::from_u32(self.krate); + let krate = cdata.map_encoded_cnum_to_current(krate); + DefId { krate, index: DefIndex::from_u32(self.index) } + } +} + #[derive(Encodable, Decodable)] crate struct CrateDep { pub name: Symbol, @@ -309,7 +333,7 @@ define_tables! { mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>, promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>, thir_abstract_const: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>, - impl_parent: Table<DefIndex, Lazy!(DefId)>, + impl_parent: Table<DefIndex, RawDefId>, impl_polarity: Table<DefIndex, ty::ImplPolarity>, impl_constness: Table<DefIndex, hir::Constness>, impl_defaultness: Table<DefIndex, hir::Defaultness>, @@ -322,7 +346,7 @@ define_tables! { generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>, trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>, - trait_item_def_id: Table<DefIndex, Lazy<DefId>>, + trait_item_def_id: Table<DefIndex, RawDefId>, inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>, expn_that_defined: Table<DefIndex, Lazy<ExpnId>>, unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 3e0aa0728df..b336649d366 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -200,6 +200,34 @@ impl FixedSizeEncoding for Option<DefPathHash> { } } +// We directly encode RawDefId because using a `Lazy` would incur a 50% overhead in the worst case. +impl FixedSizeEncoding for Option<RawDefId> { + fixed_size_encoding_byte_len_and_defaults!(2 * u32::BYTE_LEN); + + #[inline] + fn from_bytes(b: &[u8]) -> Self { + let krate = u32::from_bytes(&b[0..4]); + let index = u32::from_bytes(&b[4..8]); + if krate == 0 { + return None; + } + Some(RawDefId { krate: krate - 1, index }) + } + + #[inline] + fn write_to_bytes(self, b: &mut [u8]) { + match self { + None => 0u32.write_to_bytes(b), + Some(RawDefId { krate, index }) => { + // CrateNum is less than `CrateNum::MAX_AS_U32`. + debug_assert!(krate < u32::MAX); + (1 + krate).write_to_bytes(&mut b[0..4]); + index.write_to_bytes(&mut b[4..8]); + } + } + } +} + // NOTE(eddyb) there could be an impl for `usize`, which would enable a more // generic `Lazy<T>` impl, but in the general case we might not need / want to // fit every `usize` in `u32`. |
