Skip to content

Commit 67421bd

Browse files
committed
rustc_metadata: replace PerDefTable<T> with Table<DefIndex, T>.
1 parent 876a72a commit 67421bd

File tree

4 files changed

+68
-113
lines changed

4 files changed

+68
-113
lines changed

src/librustc_metadata/rmeta/decoder.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Decoding metadata from a single crate's metadata
22

33
use crate::rmeta::*;
4-
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
4+
use crate::rmeta::table::{FixedSizeEncoding, Table};
55

6-
use rustc_index::vec::IndexVec;
6+
use rustc_index::vec::{Idx, IndexVec};
77
use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
88
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
99
use rustc::hir::map::definitions::DefPathTable;
@@ -341,10 +341,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a,
341341
}
342342
}
343343

344-
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx>
344+
impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>>> for DecodeContext<'a, 'tcx>
345345
where Option<T>: FixedSizeEncoding,
346346
{
347-
fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> {
347+
fn specialized_decode(&mut self) -> Result<Lazy<Table<I, T>>, Self::Error> {
348348
let len = self.read_usize()?;
349349
self.read_lazy_with_meta(len)
350350
}

src/librustc_metadata/rmeta/encoder.rs

+27-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::rmeta::*;
2-
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
2+
use crate::rmeta::table::{FixedSizeEncoding, Table};
33

44
use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
55
EncodedMetadata, ForeignModule};
@@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId,
88
use rustc::hir::{GenericParamKind, AnonConst};
99
use rustc::hir::map::definitions::DefPathTable;
1010
use rustc_data_structures::fingerprint::Fingerprint;
11-
use rustc_index::vec::IndexVec;
11+
use rustc_index::vec::{Idx, IndexVec};
1212
use rustc::middle::dependency_format::Linkage;
1313
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
1414
metadata_symbol_name};
@@ -62,26 +62,26 @@ struct EncodeContext<'tcx> {
6262

6363
#[derive(Default)]
6464
struct PerDefTables<'tcx> {
65-
kind: PerDefTable<Lazy<EntryKind<'tcx>>>,
66-
visibility: PerDefTable<Lazy<ty::Visibility>>,
67-
span: PerDefTable<Lazy<Span>>,
68-
attributes: PerDefTable<Lazy<[ast::Attribute]>>,
69-
children: PerDefTable<Lazy<[DefIndex]>>,
70-
stability: PerDefTable<Lazy<attr::Stability>>,
71-
deprecation: PerDefTable<Lazy<attr::Deprecation>>,
72-
73-
ty: PerDefTable<Lazy<Ty<'tcx>>>,
74-
fn_sig: PerDefTable<Lazy<ty::PolyFnSig<'tcx>>>,
75-
impl_trait_ref: PerDefTable<Lazy<ty::TraitRef<'tcx>>>,
76-
inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
77-
variances: PerDefTable<Lazy<[ty::Variance]>>,
78-
generics: PerDefTable<Lazy<ty::Generics>>,
79-
explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
80-
inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
81-
super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
82-
83-
mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
84-
promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
65+
kind: Table<DefIndex, Lazy<EntryKind<'tcx>>>,
66+
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
67+
span: Table<DefIndex, Lazy<Span>>,
68+
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
69+
children: Table<DefIndex, Lazy<[DefIndex]>>,
70+
stability: Table<DefIndex, Lazy<attr::Stability>>,
71+
deprecation: Table<DefIndex, Lazy<attr::Deprecation>>,
72+
73+
ty: Table<DefIndex, Lazy<Ty<'tcx>>>,
74+
fn_sig: Table<DefIndex, Lazy<ty::PolyFnSig<'tcx>>>,
75+
impl_trait_ref: Table<DefIndex, Lazy<ty::TraitRef<'tcx>>>,
76+
inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
77+
variances: Table<DefIndex, Lazy<[ty::Variance]>>,
78+
generics: Table<DefIndex, Lazy<ty::Generics>>,
79+
explicit_predicates: Table<DefIndex, Lazy<ty::GenericPredicates<'tcx>>>,
80+
inferred_outlives: Table<DefIndex, Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
81+
super_predicates: Table<DefIndex, Lazy<ty::GenericPredicates<'tcx>>>,
82+
83+
mir: Table<DefIndex, Lazy<mir::Body<'tcx>>>,
84+
promoted_mir: Table<DefIndex, Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
8585
}
8686

8787
macro_rules! encoder_methods {
@@ -138,10 +138,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
138138
}
139139
}
140140

141-
impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx>
141+
impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>>> for EncodeContext<'tcx>
142142
where Option<T>: FixedSizeEncoding,
143143
{
144-
fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> {
144+
fn specialized_encode(&mut self, lazy: &Lazy<Table<I, T>>) -> Result<(), Self::Error> {
145145
self.emit_usize(lazy.meta)?;
146146
self.emit_lazy_distance(*lazy)
147147
}
@@ -307,14 +307,14 @@ impl<I, T: Encodable> EncodeContentsForLazy<[T]> for I
307307
}
308308
}
309309

310-
// Shorthand for `$self.$tables.$table.set($key, $self.lazy($value))`, which would
310+
// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy($value))`, which would
311311
// normally need extra variables to avoid errors about multiple mutable borrows.
312312
macro_rules! record {
313-
($self:ident.$tables:ident.$table:ident[$key:expr] <- $value:expr) => {{
313+
($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
314314
{
315315
let value = $value;
316316
let lazy = $self.lazy(value);
317-
$self.$tables.$table.set($key, lazy);
317+
$self.$tables.$table.set($def_id.index, lazy);
318318
}
319319
}}
320320
}

src/librustc_metadata/rmeta/mod.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use decoder::Metadata;
2-
use table::PerDefTable;
2+
use table::Table;
33

44
use rustc::hir;
55
use rustc::hir::def::{self, CtorKind};
@@ -166,8 +166,7 @@ enum LazyState {
166166
// manually, instead of relying on the default, to get the correct variance.
167167
// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
168168
macro_rules! Lazy {
169-
(Table<$T:ty>) => {Lazy<Table<$T>, usize>};
170-
(PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>};
169+
(Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
171170
([$T:ty]) => {Lazy<[$T], usize>};
172171
($T:ty) => {Lazy<$T, ()>};
173172
}
@@ -234,29 +233,29 @@ crate struct TraitImpls {
234233

235234
#[derive(RustcEncodable, RustcDecodable)]
236235
crate struct LazyPerDefTables<'tcx> {
237-
kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
238-
visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
239-
span: Lazy!(PerDefTable<Lazy<Span>>),
240-
attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
241-
children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
242-
stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
243-
deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
244-
ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
245-
fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
246-
impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
247-
inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
248-
variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
249-
generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
250-
explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
236+
kind: Lazy!(Table<DefIndex, Lazy!(EntryKind<'tcx>)>),
237+
visibility: Lazy!(Table<DefIndex, Lazy<ty::Visibility>>),
238+
span: Lazy!(Table<DefIndex, Lazy<Span>>),
239+
attributes: Lazy!(Table<DefIndex, Lazy<[ast::Attribute]>>),
240+
children: Lazy!(Table<DefIndex, Lazy<[DefIndex]>>),
241+
stability: Lazy!(Table<DefIndex, Lazy<attr::Stability>>),
242+
deprecation: Lazy!(Table<DefIndex, Lazy<attr::Deprecation>>),
243+
ty: Lazy!(Table<DefIndex, Lazy!(Ty<'tcx>)>),
244+
fn_sig: Lazy!(Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>),
245+
impl_trait_ref: Lazy!(Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>),
246+
inherent_impls: Lazy!(Table<DefIndex, Lazy<[DefIndex]>>),
247+
variances: Lazy!(Table<DefIndex, Lazy<[ty::Variance]>>),
248+
generics: Lazy!(Table<DefIndex, Lazy<ty::Generics>>),
249+
explicit_predicates: Lazy!(Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>),
251250
// FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
252251
// doesn't handle shorthands in its own (de)serialization impls,
253252
// as it's an `enum` for which we want to derive (de)serialization,
254253
// so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
255254
// Also, as an optimization, a missing entry indicates an empty `&[]`.
256-
inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
257-
super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
258-
mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
259-
promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
255+
inferred_outlives: Lazy!(Table<DefIndex, Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
256+
super_predicates: Lazy!(Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>),
257+
mir: Lazy!(Table<DefIndex, Lazy!(mir::Body<'tcx>)>),
258+
promoted_mir: Lazy!(Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
260259
}
261260

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

src/librustc_metadata/rmeta/table.rs

+17-61
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::rmeta::*;
22

3-
use rustc::hir::def_id::{DefId, DefIndex};
3+
use rustc_index::vec::Idx;
44
use rustc_serialize::{Encodable, opaque::Encoder};
55
use std::convert::TryInto;
66
use std::marker::PhantomData;
@@ -125,14 +125,16 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
125125
// FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
126126
// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
127127
// (not sure if that is possible given that the `Vec` is being resized now)
128-
pub(super) struct Table<T> where Option<T>: FixedSizeEncoding {
129-
// FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
130-
// once that starts being allowed by the compiler (i.e. lazy normalization).
128+
pub(super) struct Table<I: Idx, T> where Option<T>: FixedSizeEncoding {
129+
// FIXME(eddyb) use `IndexVec<I, [u8; <Option<T>>::BYTE_LEN]>` instead of
130+
// `Vec<u8>`, once that starts working (i.e. lazy normalization).
131+
// Then again, that has the downside of not allowing `Table::encode` to
132+
// obtain a `&[u8]` entirely in safe code, for writing the bytes out.
131133
bytes: Vec<u8>,
132-
_marker: PhantomData<T>,
134+
_marker: PhantomData<(fn(&I), T)>,
133135
}
134136

135-
impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
137+
impl<I: Idx, T> Default for Table<I, T> where Option<T>: FixedSizeEncoding {
136138
fn default() -> Self {
137139
Table {
138140
bytes: vec![],
@@ -141,13 +143,14 @@ impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
141143
}
142144
}
143145

144-
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
145-
fn set(&mut self, i: usize, value: T) {
146+
impl<I: Idx, T> Table<I, T> where Option<T>: FixedSizeEncoding {
147+
pub(super) fn set(&mut self, i: I, value: T) {
146148
// FIXME(eddyb) investigate more compact encodings for sparse tables.
147149
// On the PR @michaelwoerister mentioned:
148150
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
149151
// > trick (i.e. divide things into buckets of 32 or 64 items and then
150152
// > store bit-masks of which item in each bucket is actually serialized).
153+
let i = i.index();
151154
let needed = (i + 1) * <Option<T>>::BYTE_LEN;
152155
if self.bytes.len() < needed {
153156
self.bytes.resize(needed, 0);
@@ -156,7 +159,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
156159
Some(value).write_to_bytes_at(&mut self.bytes, i);
157160
}
158161

159-
fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
162+
pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
160163
let pos = buf.position();
161164
buf.emit_raw_bytes(&self.bytes);
162165
Lazy::from_position_and_meta(
@@ -166,73 +169,26 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
166169
}
167170
}
168171

169-
impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
172+
impl<I: Idx, T> LazyMeta for Table<I, T> where Option<T>: FixedSizeEncoding {
170173
type Meta = usize;
171174

172175
fn min_size(len: usize) -> usize {
173176
len
174177
}
175178
}
176179

177-
impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
180+
impl<I: Idx, T> Lazy<Table<I, T>> where Option<T>: FixedSizeEncoding {
178181
/// Given the metadata, extract out the value at a particular index (if any).
179182
#[inline(never)]
180-
fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
183+
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
181184
&self,
182185
metadata: M,
183-
i: usize,
186+
i: I,
184187
) -> Option<T> {
185188
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
186189

187190
let start = self.position.get();
188191
let bytes = &metadata.raw_bytes()[start..start + self.meta];
189-
<Option<T>>::maybe_read_from_bytes_at(bytes, i)?
190-
}
191-
}
192-
193-
/// Like a `Table` but using `DefIndex` instead of `usize` as keys.
194-
// FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
195-
// and by using `newtype_index!` to define `DefIndex`.
196-
pub(super) struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
197-
198-
impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
199-
fn default() -> Self {
200-
PerDefTable(Table::default())
201-
}
202-
}
203-
204-
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
205-
pub(super) fn set(&mut self, def_id: DefId, value: T) {
206-
assert!(def_id.is_local());
207-
self.0.set(def_id.index.index(), value);
208-
}
209-
210-
pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
211-
let lazy = self.0.encode(buf);
212-
Lazy::from_position_and_meta(lazy.position, lazy.meta)
213-
}
214-
}
215-
216-
impl<T> LazyMeta for PerDefTable<T> where Option<T>: FixedSizeEncoding {
217-
type Meta = <Table<T> as LazyMeta>::Meta;
218-
219-
fn min_size(meta: Self::Meta) -> usize {
220-
Table::<T>::min_size(meta)
221-
}
222-
}
223-
224-
impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding {
225-
fn as_table(&self) -> Lazy<Table<T>> {
226-
Lazy::from_position_and_meta(self.position, self.meta)
227-
}
228-
229-
/// Given the metadata, extract out the value at a particular DefIndex (if any).
230-
#[inline(never)]
231-
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
232-
&self,
233-
metadata: M,
234-
def_index: DefIndex,
235-
) -> Option<T> {
236-
self.as_table().get(metadata, def_index.index())
192+
<Option<T>>::maybe_read_from_bytes_at(bytes, i.index())?
237193
}
238194
}

0 commit comments

Comments
 (0)