Skip to content

Commit 34066d6

Browse files
committed
rustc_metadata: don't use more space than needed, for each Table.
1 parent ee747f6 commit 34066d6

File tree

2 files changed

+21
-33
lines changed

2 files changed

+21
-33
lines changed

src/librustc_metadata/encoder.rs

+2-20
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct EncodeContext<'tcx> {
6060
source_file_cache: Lrc<SourceFile>,
6161
}
6262

63+
#[derive(Default)]
6364
struct PerDefTables<'tcx> {
6465
kind: PerDefTable<Lazy<EntryKind<'tcx>>>,
6566
visibility: PerDefTable<Lazy<ty::Visibility>>,
@@ -1774,29 +1775,10 @@ crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
17741775
// Since encoding metadata is not in a query, and nothing is cached,
17751776
// there's no need to do dep-graph tracking for any of it.
17761777
let (root, mut result) = tcx.dep_graph.with_ignore(move || {
1777-
let def_count = tcx.hir().definitions().def_index_count();
17781778
let mut ecx = EncodeContext {
17791779
opaque: encoder,
17801780
tcx,
1781-
per_def: PerDefTables {
1782-
kind: PerDefTable::new(def_count),
1783-
visibility: PerDefTable::new(def_count),
1784-
span: PerDefTable::new(def_count),
1785-
attributes: PerDefTable::new(def_count),
1786-
children: PerDefTable::new(def_count),
1787-
stability: PerDefTable::new(def_count),
1788-
deprecation: PerDefTable::new(def_count),
1789-
1790-
ty: PerDefTable::new(def_count),
1791-
inherent_impls: PerDefTable::new(def_count),
1792-
variances: PerDefTable::new(def_count),
1793-
generics: PerDefTable::new(def_count),
1794-
predicates: PerDefTable::new(def_count),
1795-
predicates_defined_on: PerDefTable::new(def_count),
1796-
1797-
mir: PerDefTable::new(def_count),
1798-
promoted_mir: PerDefTable::new(def_count),
1799-
},
1781+
per_def: Default::default(),
18001782
lazy_state: LazyState::NoNode,
18011783
type_shorthands: Default::default(),
18021784
predicate_shorthands: Default::default(),

src/librustc_metadata/table.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ crate trait FixedSizeEncoding: Default {
2323
// FIXME(eddyb) make these generic functions, or at least defaults here.
2424
// (same problem as above, needs `[u8; Self::BYTE_LEN]`)
2525
// For now, a macro (`fixed_size_encoding_byte_len_and_defaults`) is used.
26-
fn read_from_bytes_at(b: &[u8], i: usize) -> Self;
26+
fn maybe_read_from_bytes_at(b: &[u8], i: usize) -> Option<Self>;
2727
fn write_to_bytes_at(self, b: &mut [u8], i: usize);
2828
}
2929

3030
// HACK(eddyb) this shouldn't be needed (see comments on the methods above).
3131
macro_rules! fixed_size_encoding_byte_len_and_defaults {
3232
($byte_len:expr) => {
3333
const BYTE_LEN: usize = $byte_len;
34-
fn read_from_bytes_at(b: &[u8], i: usize) -> Self {
34+
fn maybe_read_from_bytes_at(b: &[u8], i: usize) -> Option<Self> {
3535
const BYTE_LEN: usize = $byte_len;
3636
// HACK(eddyb) ideally this would be done with fully safe code,
3737
// but slicing `[u8]` with `i * N..` is optimized worse, due to the
@@ -42,7 +42,7 @@ macro_rules! fixed_size_encoding_byte_len_and_defaults {
4242
b.len() / BYTE_LEN,
4343
)
4444
};
45-
FixedSizeEncoding::from_bytes(&b[i])
45+
b.get(i).map(|b| FixedSizeEncoding::from_bytes(b))
4646
}
4747
fn write_to_bytes_at(self, b: &mut [u8], i: usize) {
4848
const BYTE_LEN: usize = $byte_len;
@@ -116,25 +116,29 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
116116
/// encoding or decoding all the values eagerly and in-order.
117117
// FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
118118
// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
119-
// Sadly, that doesn't work for `DefPerTable`, which is `(Table<T>, Table<T>)`,
120-
// and so would need two lengths in its metadata, which is not supported yet.
119+
// (not sure if that is possible given that the `Vec` is being resized now)
121120
crate struct Table<T> where Option<T>: FixedSizeEncoding {
122121
// FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
123122
// once that starts being allowed by the compiler (i.e. lazy normalization).
124123
bytes: Vec<u8>,
125124
_marker: PhantomData<T>,
126125
}
127126

128-
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
129-
crate fn new(len: usize) -> Self {
127+
impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
128+
fn default() -> Self {
130129
Table {
131-
// FIXME(eddyb) only allocate and encode as many entries as needed.
132-
bytes: vec![0; len * <Option<T>>::BYTE_LEN],
130+
bytes: vec![],
133131
_marker: PhantomData,
134132
}
135133
}
134+
}
136135

136+
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
137137
crate fn set(&mut self, i: usize, value: T) {
138+
let needed = (i + 1) * <Option<T>>::BYTE_LEN;
139+
if self.bytes.len() < needed {
140+
self.bytes.resize(needed, 0);
141+
}
138142
Some(value).write_to_bytes_at(&mut self.bytes, i);
139143
}
140144

@@ -167,7 +171,7 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
167171
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
168172

169173
let bytes = &metadata.raw_bytes()[self.position.get()..][..self.meta];
170-
<Option<T>>::read_from_bytes_at(bytes, i)
174+
<Option<T>>::maybe_read_from_bytes_at(bytes, i)?
171175
}
172176
}
173177

@@ -176,11 +180,13 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
176180
// and by using `newtype_index!` to define `DefIndex`.
177181
crate struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
178182

179-
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
180-
crate fn new(def_index_count: usize) -> Self {
181-
PerDefTable(Table::new(def_index_count))
183+
impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
184+
fn default() -> Self {
185+
PerDefTable(Table::default())
182186
}
187+
}
183188

189+
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
184190
crate fn set(&mut self, def_id: DefId, value: T) {
185191
assert!(def_id.is_local());
186192
self.0.set(def_id.index.index(), value);

0 commit comments

Comments
 (0)