Skip to content

Commit b9287a8

Browse files
committed
Directly encode DefId in metadata.
1 parent 6142f50 commit b9287a8

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,17 @@ impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DeprecationEntry>>
388388
}
389389
}
390390

391+
impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DefId>> for Option<RawDefId> {
392+
fn decode_query(
393+
self,
394+
cdata: CrateMetadataRef<'a>,
395+
_: TyCtxt<'tcx>,
396+
_: impl FnOnce() -> !,
397+
) -> Option<DefId> {
398+
self.map(|raw_def_id| raw_def_id.decode(cdata))
399+
}
400+
}
401+
391402
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
392403
#[inline]
393404
fn tcx(&self) -> TyCtxt<'tcx> {
@@ -406,8 +417,9 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
406417
self.cdata.unwrap()
407418
}
408419

420+
#[inline]
409421
fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
410-
if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
422+
self.cdata().map_encoded_cnum_to_current(cnum)
411423
}
412424

413425
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
718730
}
719731
}
720732

721-
impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
722-
for Lazy<Table<I, T>>
733+
impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for Lazy<Table<I, T>>
723734
where
724735
Option<T>: FixedSizeEncoding,
725736
{
@@ -856,6 +867,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
856867
self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
857868
}
858869

870+
#[inline]
871+
pub(super) fn map_encoded_cnum_to_current(self, cnum: CrateNum) -> CrateNum {
872+
if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] }
873+
}
874+
859875
fn kind(self, item_id: DefIndex) -> EntryKind {
860876
self.maybe_kind(item_id).unwrap_or_else(|| {
861877
bug!(

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a
147147
}
148148
}
149149

150-
impl<'a, 'tcx, I: Idx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
151-
for Lazy<Table<I, T>>
150+
impl<'a, 'tcx, I: Idx, T> Encodable<EncodeContext<'a, 'tcx>> for Lazy<Table<I, T>>
152151
where
153152
Option<T>: FixedSizeEncoding,
154153
{
@@ -1285,7 +1284,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12851284
self.encode_ident_span(def_id, impl_item.ident(self.tcx));
12861285
self.encode_item_type(def_id);
12871286
if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
1288-
record!(self.tables.trait_item_def_id[def_id] <- trait_item_def_id);
1287+
self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into());
12891288
}
12901289
if impl_item.kind == ty::AssocKind::Fn {
12911290
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@@ -1457,7 +1456,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14571456
let trait_def = self.tcx.trait_def(trait_ref.def_id);
14581457
if let Some(mut an) = trait_def.ancestors(self.tcx, def_id).ok() {
14591458
if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
1460-
record!(self.tables.impl_parent[def_id] <- parent);
1459+
self.tables.impl_parent.set(def_id.index, parent.into());
14611460
}
14621461
}
14631462

compiler/rustc_metadata/src/rmeta/mod.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::creader::CrateMetadataRef;
12
use decoder::Metadata;
23
use def_path_hash_map::DefPathHashMapRef;
34
use table::{Table, TableBuilder};
@@ -8,7 +9,7 @@ use rustc_data_structures::svh::Svh;
89
use rustc_data_structures::sync::MetadataRef;
910
use rustc_hir as hir;
1011
use rustc_hir::def::{CtorKind, DefKind};
11-
use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId};
12+
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
1213
use rustc_hir::definitions::DefKey;
1314
use rustc_hir::lang_items;
1415
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
@@ -237,6 +238,29 @@ crate struct CrateRoot<'tcx> {
237238
symbol_mangling_version: SymbolManglingVersion,
238239
}
239240

241+
/// On-disk representation of `DefId`.
242+
/// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
243+
/// representation and the compilation session.
244+
#[derive(Copy, Clone)]
245+
crate struct RawDefId {
246+
krate: u32,
247+
index: u32,
248+
}
249+
250+
impl Into<RawDefId> for DefId {
251+
fn into(self) -> RawDefId {
252+
RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() }
253+
}
254+
}
255+
256+
impl RawDefId {
257+
fn decode(self, cdata: CrateMetadataRef<'_>) -> DefId {
258+
let krate = CrateNum::from_u32(self.krate);
259+
let krate = cdata.map_encoded_cnum_to_current(krate);
260+
DefId { krate, index: DefIndex::from_u32(self.index) }
261+
}
262+
}
263+
240264
#[derive(Encodable, Decodable)]
241265
crate struct CrateDep {
242266
pub name: Symbol,
@@ -309,7 +333,7 @@ define_tables! {
309333
mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
310334
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
311335
thir_abstract_const: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
312-
impl_parent: Table<DefIndex, Lazy!(DefId)>,
336+
impl_parent: Table<DefIndex, RawDefId>,
313337
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
314338
impl_constness: Table<DefIndex, hir::Constness>,
315339
impl_defaultness: Table<DefIndex, hir::Defaultness>,
@@ -322,7 +346,7 @@ define_tables! {
322346
generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
323347
trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
324348

325-
trait_item_def_id: Table<DefIndex, Lazy<DefId>>,
349+
trait_item_def_id: Table<DefIndex, RawDefId>,
326350
inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
327351
expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
328352
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,

compiler/rustc_metadata/src/rmeta/table.rs

+28
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,34 @@ impl FixedSizeEncoding for Option<DefPathHash> {
200200
}
201201
}
202202

203+
// We directly encode RawDefId because using a `Lazy` would incur a 50% overhead in the worst case.
204+
impl FixedSizeEncoding for Option<RawDefId> {
205+
fixed_size_encoding_byte_len_and_defaults!(2 * u32::BYTE_LEN);
206+
207+
#[inline]
208+
fn from_bytes(b: &[u8]) -> Self {
209+
let krate = u32::from_bytes(&b[0..4]);
210+
let index = u32::from_bytes(&b[4..8]);
211+
if krate == 0 {
212+
return None;
213+
}
214+
Some(RawDefId { krate: krate - 1, index })
215+
}
216+
217+
#[inline]
218+
fn write_to_bytes(self, b: &mut [u8]) {
219+
match self {
220+
None => 0u32.write_to_bytes(b),
221+
Some(RawDefId { krate, index }) => {
222+
// CrateNum is less than `CrateNum::MAX_AS_U32`.
223+
debug_assert!(krate < u32::MAX);
224+
(1 + krate).write_to_bytes(&mut b[0..4]);
225+
index.write_to_bytes(&mut b[4..8]);
226+
}
227+
}
228+
}
229+
}
230+
203231
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
204232
// generic `Lazy<T>` impl, but in the general case we might not need / want to
205233
// fit every `usize` in `u32`.

0 commit comments

Comments
 (0)