Directly encode DefId in metadata.
This commit is contained in:
parent
6142f50845
commit
b9287a83c5
@ -388,6 +388,17 @@ fn decode_query(
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn cdata(&self) -> CrateMetadataRef<'a> {
|
||||
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 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn maybe_kind(self, item_id: DefIndex) -> Option<EntryKind> {
|
||||
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!(
|
||||
|
@ -147,8 +147,7 @@ fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) {
|
||||
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 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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::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 @@ macro_rules! Lazy {
|
||||
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 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
|
||||
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 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
|
||||
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>>>,
|
||||
|
@ -200,6 +200,34 @@ fn write_to_bytes(self, b: &mut [u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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`.
|
||||
|
Loading…
Reference in New Issue
Block a user