Skip to content

Commit 119c788

Browse files
committed
Encode trait impls using nested Tables
We now decode trait impls DefIds only as needed.
1 parent fa36f96 commit 119c788

File tree

4 files changed

+58
-60
lines changed

4 files changed

+58
-60
lines changed

src/librustc_metadata/rmeta/decoder.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ crate struct CrateMetadata {
7575
/// quickly retrace a `DefPath`, which is needed for incremental
7676
/// compilation support.
7777
def_path_table: DefPathTable,
78-
/// Trait impl data.
79-
/// FIXME: Used only from queries and can use query cache,
80-
/// so pre-decoding can probably be avoided.
81-
trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>,
8278
/// Proc macro descriptions for this crate, if it's a proc macro crate.
8379
raw_proc_macros: Option<&'static [ProcMacro]>,
8480
/// Source maps for code from the crate.
@@ -1304,17 +1300,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13041300
None => None,
13051301
};
13061302

1307-
if let Some(filter) = filter {
1308-
if let Some(impls) = self.trait_impls.get(&filter) {
1303+
if let Some((cnum, index)) = filter {
1304+
if let Some(impls) =
1305+
self.root.tables.trait_impls.get(self, cnum).and_then(|t| t.get(self, index))
1306+
{
13091307
tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx)))
13101308
} else {
13111309
&[]
13121310
}
13131311
} else {
13141312
tcx.arena.alloc_from_iter(
1315-
self.trait_impls
1316-
.values()
1317-
.flat_map(|impls| impls.decode(self).map(|idx| self.local_def_id(idx))),
1313+
self.root.all_trait_impls.decode(self).map(|idx| self.local_def_id(idx)),
13181314
)
13191315
}
13201316
}
@@ -1646,19 +1642,13 @@ impl CrateMetadata {
16461642
let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || {
16471643
root.def_path_table.decode((&blob, sess))
16481644
});
1649-
let trait_impls = root
1650-
.impls
1651-
.decode((&blob, sess))
1652-
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
1653-
.collect();
16541645
let alloc_decoding_state =
16551646
AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
16561647
let dependencies = Lock::new(cnum_map.iter().cloned().collect());
16571648
CrateMetadata {
16581649
blob,
16591650
root,
16601651
def_path_table,
1661-
trait_impls,
16621652
raw_proc_macros,
16631653
source_map_import_info: OnceCell::new(),
16641654
alloc_decoding_state,

src/librustc_metadata/rmeta/encoder.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
564564

565565
// Encode the def IDs of impls, for coherence checking.
566566
i = self.position();
567-
let impls = self.encode_impls();
567+
let all_trait_impls = self.encode_trait_impls();
568568
let impl_bytes = self.position() - i;
569569

570570
let tcx = self.tcx;
@@ -677,12 +677,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
677677
foreign_modules,
678678
source_map,
679679
def_path_table,
680-
impls,
681680
exported_symbols,
682681
interpret_alloc_index,
683682
tables,
684683
syntax_contexts,
685684
expn_data,
685+
all_trait_impls,
686686
});
687687

688688
let total_bytes = self.position();
@@ -1586,34 +1586,37 @@ impl EncodeContext<'a, 'tcx> {
15861586
self.lazy(&tcx.lang_items().missing)
15871587
}
15881588

1589-
/// Encodes an index, mapping each trait to its (local) implementations.
1590-
fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
1589+
fn encode_trait_impls(&mut self) -> Lazy<[DefIndex]> {
15911590
debug!("EncodeContext::encode_impls()");
15921591
let tcx = self.tcx;
15931592
let mut visitor = ImplVisitor { tcx, impls: FxHashMap::default() };
15941593
tcx.hir().krate().visit_all_item_likes(&mut visitor);
15951594

1596-
let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
1595+
let all_impls: Vec<_> = visitor.impls.into_iter().collect();
1596+
let mut all_trait_impls = Vec::new();
15971597

1598-
// Bring everything into deterministic order for hashing
1599-
all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
1598+
let mut table_map: FxHashMap<u32, TableBuilder<DefIndex, Lazy<[DefIndex]>>> =
1599+
Default::default();
16001600

1601-
let all_impls: Vec<_> = all_impls
1602-
.into_iter()
1603-
.map(|(trait_def_id, mut impls)| {
1604-
// Bring everything into deterministic order for hashing
1605-
impls.sort_by_cached_key(|&index| {
1606-
tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index })
1607-
});
1601+
for (trait_def_id, mut impls) in all_impls {
1602+
// Bring everything into deterministic order for hashing
1603+
impls.sort_by_cached_key(|&index| {
1604+
tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index })
1605+
});
16081606

1609-
TraitImpls {
1610-
trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
1611-
impls: self.lazy(&impls),
1612-
}
1613-
})
1614-
.collect();
1607+
all_trait_impls.extend(&impls);
16151608

1616-
self.lazy(&all_impls)
1609+
table_map
1610+
.entry(trait_def_id.krate.as_u32())
1611+
.or_default()
1612+
.set(trait_def_id.index, self.lazy(&impls));
1613+
}
1614+
1615+
for (cnum, builder) in table_map {
1616+
let table = builder.encode(&mut self.opaque);
1617+
self.tables.trait_impls.set(cnum, table);
1618+
}
1619+
self.lazy(&all_trait_impls)
16171620
}
16181621

16191622
// Encodes all symbols exported from this crate into the metadata.

src/librustc_metadata/rmeta/mod.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ crate struct CrateRoot<'tcx> {
197197
native_libraries: Lazy<[NativeLib]>,
198198
foreign_modules: Lazy<[ForeignModule]>,
199199
def_path_table: Lazy<rustc_hir::definitions::DefPathTable>,
200-
impls: Lazy<[TraitImpls]>,
200+
all_trait_impls: Lazy<[DefIndex]>,
201201
interpret_alloc_index: Lazy<[u32]>,
202202

203203
tables: LazyTables<'tcx>,
@@ -230,23 +230,17 @@ crate struct CrateDep {
230230
pub extra_filename: String,
231231
}
232232

233-
#[derive(RustcEncodable, RustcDecodable)]
234-
crate struct TraitImpls {
235-
trait_id: (u32, DefIndex),
236-
impls: Lazy<[DefIndex]>,
237-
}
238-
239233
/// Define `LazyTables` and `TableBuilders` at the same time.
240234
macro_rules! define_tables {
241-
($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
235+
($($name:ident: Table<$I:ty, $T:ty>),+ $(,)?) => {
242236
#[derive(RustcEncodable, RustcDecodable)]
243237
crate struct LazyTables<'tcx> {
244-
$($name: Lazy!(Table<DefIndex, $T>)),+
238+
$($name: Lazy!(Table<$I, $T>)),+
245239
}
246240

247241
#[derive(Default)]
248242
struct TableBuilders<'tcx> {
249-
$($name: TableBuilder<DefIndex, $T>),+
243+
$($name: TableBuilder<$I, $T>),+
250244
}
251245

252246
impl TableBuilders<'tcx> {
@@ -286,6 +280,7 @@ define_tables! {
286280
mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
287281
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
288282
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u64>>>,
283+
trait_impls: Table<u32, Lazy!(Table<DefIndex, Lazy!([DefIndex])>)>,
289284
}
290285

291286
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]

src/librustc_metadata/rmeta/table.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,34 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<T>> {
9393
}
9494
}
9595

96-
impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
97-
fixed_size_encoding_byte_len_and_defaults!(u32::BYTE_LEN * 2);
96+
macro_rules! meta_body {
97+
($T:ident) => {
98+
fixed_size_encoding_byte_len_and_defaults!(u32::BYTE_LEN * 2);
99+
100+
fn from_bytes(b: &[u8]) -> Self {
101+
Some(Lazy::from_position_and_meta(
102+
<Option<Lazy<$T>>>::from_bytes(b)?.position,
103+
u32::from_bytes(&b[u32::BYTE_LEN..]) as usize,
104+
))
105+
}
98106

99-
fn from_bytes(b: &[u8]) -> Self {
100-
Some(Lazy::from_position_and_meta(
101-
<Option<Lazy<T>>>::from_bytes(b)?.position,
102-
u32::from_bytes(&b[u32::BYTE_LEN..]) as usize,
103-
))
104-
}
107+
fn write_to_bytes(self, b: &mut [u8]) {
108+
self.map(|lazy| Lazy::<$T>::from_position(lazy.position)).write_to_bytes(b);
105109

106-
fn write_to_bytes(self, b: &mut [u8]) {
107-
self.map(|lazy| Lazy::<T>::from_position(lazy.position)).write_to_bytes(b);
110+
let len = self.map_or(0, |lazy| lazy.meta);
111+
let len: u32 = len.try_into().unwrap();
112+
113+
len.write_to_bytes(&mut b[u32::BYTE_LEN..]);
114+
}
115+
};
116+
}
108117

109-
let len = self.map_or(0, |lazy| lazy.meta);
110-
let len: u32 = len.try_into().unwrap();
118+
impl<I: Idx, T: Encodable> FixedSizeEncoding for Option<Lazy<Table<I, Lazy<[T], usize>>, usize>> {
119+
meta_body!(T);
120+
}
111121

112-
len.write_to_bytes(&mut b[u32::BYTE_LEN..]);
113-
}
122+
impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
123+
meta_body!(T);
114124
}
115125

116126
/// Random-access table (i.e. offering constant-time `get`/`set`), similar to

0 commit comments

Comments
 (0)