diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-04-14 05:21:39 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-10-15 18:23:51 +0300 |
| commit | 34066d60c38b8e1049a60e1eaf26cd84a67e7655 (patch) | |
| tree | b8f06fcb74027c4e0f0c10c907048667afb50b29 | |
| parent | ee747f645ffdfcea4f39ad4ccc4d83742a4ea3aa (diff) | |
| download | rust-34066d60c38b8e1049a60e1eaf26cd84a67e7655.tar.gz rust-34066d60c38b8e1049a60e1eaf26cd84a67e7655.zip | |
rustc_metadata: don't use more space than needed, for each Table.
| -rw-r--r-- | src/librustc_metadata/encoder.rs | 22 | ||||
| -rw-r--r-- | src/librustc_metadata/table.rs | 32 |
2 files changed, 21 insertions, 33 deletions
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 3bc3fee4164..f1436e4c09d 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -60,6 +60,7 @@ struct EncodeContext<'tcx> { source_file_cache: Lrc<SourceFile>, } +#[derive(Default)] struct PerDefTables<'tcx> { kind: PerDefTable<Lazy<EntryKind<'tcx>>>, visibility: PerDefTable<Lazy<ty::Visibility>>, @@ -1774,29 +1775,10 @@ crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { // Since encoding metadata is not in a query, and nothing is cached, // there's no need to do dep-graph tracking for any of it. let (root, mut result) = tcx.dep_graph.with_ignore(move || { - let def_count = tcx.hir().definitions().def_index_count(); let mut ecx = EncodeContext { opaque: encoder, tcx, - per_def: PerDefTables { - kind: PerDefTable::new(def_count), - visibility: PerDefTable::new(def_count), - span: PerDefTable::new(def_count), - attributes: PerDefTable::new(def_count), - children: PerDefTable::new(def_count), - stability: PerDefTable::new(def_count), - deprecation: PerDefTable::new(def_count), - - ty: PerDefTable::new(def_count), - inherent_impls: PerDefTable::new(def_count), - variances: PerDefTable::new(def_count), - generics: PerDefTable::new(def_count), - predicates: PerDefTable::new(def_count), - predicates_defined_on: PerDefTable::new(def_count), - - mir: PerDefTable::new(def_count), - promoted_mir: PerDefTable::new(def_count), - }, + per_def: Default::default(), lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), diff --git a/src/librustc_metadata/table.rs b/src/librustc_metadata/table.rs index 0585aa1d388..5cfa137d04f 100644 --- a/src/librustc_metadata/table.rs +++ b/src/librustc_metadata/table.rs @@ -23,7 +23,7 @@ crate trait FixedSizeEncoding: Default { // FIXME(eddyb) make these generic functions, or at least defaults here. // (same problem as above, needs `[u8; Self::BYTE_LEN]`) // For now, a macro (`fixed_size_encoding_byte_len_and_defaults`) is used. - fn read_from_bytes_at(b: &[u8], i: usize) -> Self; + fn maybe_read_from_bytes_at(b: &[u8], i: usize) -> Option<Self>; fn write_to_bytes_at(self, b: &mut [u8], i: usize); } @@ -31,7 +31,7 @@ crate trait FixedSizeEncoding: Default { macro_rules! fixed_size_encoding_byte_len_and_defaults { ($byte_len:expr) => { const BYTE_LEN: usize = $byte_len; - fn read_from_bytes_at(b: &[u8], i: usize) -> Self { + fn maybe_read_from_bytes_at(b: &[u8], i: usize) -> Option<Self> { const BYTE_LEN: usize = $byte_len; // HACK(eddyb) ideally this would be done with fully safe code, // 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 { b.len() / BYTE_LEN, ) }; - FixedSizeEncoding::from_bytes(&b[i]) + b.get(i).map(|b| FixedSizeEncoding::from_bytes(b)) } fn write_to_bytes_at(self, b: &mut [u8], i: usize) { const BYTE_LEN: usize = $byte_len; @@ -116,8 +116,7 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> { /// encoding or decoding all the values eagerly and in-order. // FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used // when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it. -// Sadly, that doesn't work for `DefPerTable`, which is `(Table<T>, Table<T>)`, -// and so would need two lengths in its metadata, which is not supported yet. +// (not sure if that is possible given that the `Vec` is being resized now) crate struct Table<T> where Option<T>: FixedSizeEncoding { // FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`, // once that starts being allowed by the compiler (i.e. lazy normalization). @@ -125,16 +124,21 @@ crate struct Table<T> where Option<T>: FixedSizeEncoding { _marker: PhantomData<T>, } -impl<T> Table<T> where Option<T>: FixedSizeEncoding { - crate fn new(len: usize) -> Self { +impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding { + fn default() -> Self { Table { - // FIXME(eddyb) only allocate and encode as many entries as needed. - bytes: vec![0; len * <Option<T>>::BYTE_LEN], + bytes: vec![], _marker: PhantomData, } } +} +impl<T> Table<T> where Option<T>: FixedSizeEncoding { crate fn set(&mut self, i: usize, value: T) { + let needed = (i + 1) * <Option<T>>::BYTE_LEN; + if self.bytes.len() < needed { + self.bytes.resize(needed, 0); + } Some(value).write_to_bytes_at(&mut self.bytes, i); } @@ -167,7 +171,7 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding { debug!("Table::lookup: index={:?} len={:?}", i, self.meta); let bytes = &metadata.raw_bytes()[self.position.get()..][..self.meta]; - <Option<T>>::read_from_bytes_at(bytes, i) + <Option<T>>::maybe_read_from_bytes_at(bytes, i)? } } @@ -176,11 +180,13 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding { // and by using `newtype_index!` to define `DefIndex`. crate struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding; -impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding { - crate fn new(def_index_count: usize) -> Self { - PerDefTable(Table::new(def_index_count)) +impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding { + fn default() -> Self { + PerDefTable(Table::default()) } +} +impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding { crate fn set(&mut self, def_id: DefId, value: T) { assert!(def_id.is_local()); self.0.set(def_id.index.index(), value); |
