Skip to content

Commit 23fd5ad

Browse files
committed
rustc_metadata: don't use more space than needed, for each Table.
1 parent 12f0c3a commit 23fd5ad

File tree

2 files changed

+21
-31
lines changed

2 files changed

+21
-31
lines changed

src/librustc_metadata/encoder.rs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
5858
source_file_cache: Lrc<SourceFile>,
5959
}
6060

61+
#[derive(Default)]
6162
struct PerDefTables<'tcx> {
6263
kind: PerDefTable<Lazy<EntryKind<'tcx>>>,
6364
visibility: PerDefTable<Lazy<ty::Visibility>>,
@@ -1830,28 +1831,10 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
18301831
// Since encoding metadata is not in a query, and nothing is cached,
18311832
// there's no need to do dep-graph tracking for any of it.
18321833
let (root, mut result) = tcx.dep_graph.with_ignore(move || {
1833-
let def_counts = tcx.hir().definitions().def_index_counts_lo_hi();
18341834
let mut ecx = EncodeContext {
18351835
opaque: encoder,
18361836
tcx,
1837-
per_def: PerDefTables {
1838-
kind: PerDefTable::new(def_counts),
1839-
visibility: PerDefTable::new(def_counts),
1840-
span: PerDefTable::new(def_counts),
1841-
attributes: PerDefTable::new(def_counts),
1842-
children: PerDefTable::new(def_counts),
1843-
stability: PerDefTable::new(def_counts),
1844-
deprecation: PerDefTable::new(def_counts),
1845-
1846-
ty: PerDefTable::new(def_counts),
1847-
inherent_impls: PerDefTable::new(def_counts),
1848-
variances: PerDefTable::new(def_counts),
1849-
generics: PerDefTable::new(def_counts),
1850-
predicates: PerDefTable::new(def_counts),
1851-
predicates_defined_on: PerDefTable::new(def_counts),
1852-
1853-
mir: PerDefTable::new(def_counts),
1854-
},
1837+
per_def: Default::default(),
18551838
lazy_state: LazyState::NoNode,
18561839
type_shorthands: Default::default(),
18571840
predicate_shorthands: Default::default(),

src/librustc_metadata/table.rs

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

2929
// HACK(eddyb) this shouldn't be needed (see comments on the methods above).
3030
macro_rules! fixed_size_encoding_byte_len_and_defaults {
3131
($byte_len:expr) => {
3232
const BYTE_LEN: usize = $byte_len;
33-
fn read_from_bytes_at(b: &[u8], i: usize) -> Self {
33+
fn maybe_read_from_bytes_at(b: &[u8], i: usize) -> Option<Self> {
3434
const BYTE_LEN: usize = $byte_len;
3535
// HACK(eddyb) ideally this would be done with fully safe code,
3636
// but slicing `[u8]` with `i * N..` is optimized worse, due to the
@@ -41,7 +41,7 @@ macro_rules! fixed_size_encoding_byte_len_and_defaults {
4141
b.len() / BYTE_LEN,
4242
)
4343
};
44-
FixedSizeEncoding::from_bytes(&b[i])
44+
b.get(i).map(|b| FixedSizeEncoding::from_bytes(b))
4545
}
4646
fn write_to_bytes_at(self, b: &mut [u8], i: usize) {
4747
const BYTE_LEN: usize = $byte_len;
@@ -126,16 +126,21 @@ pub struct Table<T> where Option<T>: FixedSizeEncoding {
126126
_marker: PhantomData<T>,
127127
}
128128

129-
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
130-
pub fn new(len: usize) -> Self {
129+
impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
130+
fn default() -> Self {
131131
Table {
132-
// FIXME(eddyb) only allocate and encode as many entries as needed.
133-
bytes: vec![0; len * <Option<T>>::BYTE_LEN],
132+
bytes: vec![],
134133
_marker: PhantomData,
135134
}
136135
}
136+
}
137137

138+
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
138139
pub fn set(&mut self, i: usize, value: T) {
140+
let needed = (i + 1) * <Option<T>>::BYTE_LEN;
141+
if self.bytes.len() < needed {
142+
self.bytes.resize(needed, 0);
143+
}
139144
Some(value).write_to_bytes_at(&mut self.bytes, i);
140145
}
141146

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

170175
let bytes = &metadata.raw_bytes()[self.position.get()..][..self.meta];
171-
<Option<T>>::read_from_bytes_at(bytes, i)
176+
<Option<T>>::maybe_read_from_bytes_at(bytes, i)?
172177
}
173178
}
174179

@@ -179,14 +184,16 @@ pub struct PerDefTable<T> where Option<T>: FixedSizeEncoding {
179184
hi: Table<T>,
180185
}
181186

182-
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
183-
pub fn new((max_index_lo, max_index_hi): (usize, usize)) -> Self {
187+
impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
188+
fn default() -> Self {
184189
PerDefTable {
185-
lo: Table::new(max_index_lo),
186-
hi: Table::new(max_index_hi),
190+
lo: Table::default(),
191+
hi: Table::default(),
187192
}
188193
}
194+
}
189195

196+
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
190197
pub fn set(&mut self, def_id: DefId, value: T) {
191198
assert!(def_id.is_local());
192199
let space_index = def_id.index.address_space().index();

0 commit comments

Comments
 (0)