about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-04-13 19:18:12 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-10-15 18:23:51 +0300
commit5d52a7e0d0f230627c20dc874c17c528261a397f (patch)
tree06819560560408381a0cbe18166aa0f6a25494d0
parentdd1264e90a47d9818d868276cd09363fe78056c4 (diff)
downloadrust-5d52a7e0d0f230627c20dc874c17c528261a397f.tar.gz
rust-5d52a7e0d0f230627c20dc874c17c528261a397f.zip
rustc_metadata: split tables into an usize-keyed Table and a DefIndex-keyed PerDefTable.
-rw-r--r--src/librustc_metadata/decoder.rs6
-rw-r--r--src/librustc_metadata/encoder.rs10
-rw-r--r--src/librustc_metadata/schema.rs5
-rw-r--r--src/librustc_metadata/table.rs91
4 files changed, 75 insertions, 37 deletions
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index c2ec9115d31..c640e411f63 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -2,7 +2,7 @@
 
 use crate::cstore::{self, CrateMetadata, MetadataBlob};
 use crate::schema::*;
-use crate::table::Table;
+use crate::table::PerDefTable;
 
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::sync::{Lrc, ReadGuard};
@@ -255,10 +255,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a,
     }
 }
 
-impl<'a, 'tcx, T> SpecializedDecoder<Lazy<Table<T>>> for DecodeContext<'a, 'tcx>
+impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx>
     where T: LazyMeta<Meta = ()>,
 {
-    fn specialized_decode(&mut self) -> Result<Lazy<Table<T>>, Self::Error> {
+    fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> {
         let len = self.read_usize()?;
         self.read_lazy_with_meta(len)
     }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 53d3039a284..df99541df58 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1,5 +1,5 @@
 use crate::schema::*;
-use crate::table::Table;
+use crate::table::PerDefTable;
 
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
                             EncodedMetadata, ForeignModule};
@@ -47,7 +47,7 @@ struct EncodeContext<'tcx> {
     opaque: opaque::Encoder,
     tcx: TyCtxt<'tcx>,
 
-    entries_table: Table<Entry<'tcx>>,
+    entries_table: PerDefTable<Entry<'tcx>>,
 
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -114,10 +114,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
     }
 }
 
-impl<'tcx, T> SpecializedEncoder<Lazy<Table<T>>> for EncodeContext<'tcx>
+impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx>
     where T: LazyMeta<Meta = ()>,
 {
-    fn specialized_encode(&mut self, lazy: &Lazy<Table<T>>) -> Result<(), Self::Error> {
+    fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> {
         self.emit_usize(lazy.meta)?;
         self.emit_lazy_distance(*lazy)
     }
@@ -1925,7 +1925,7 @@ crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
         let mut ecx = EncodeContext {
             opaque: encoder,
             tcx,
-            entries_table: Table::new(tcx.hir().definitions().def_index_count()),
+            entries_table: PerDefTable::new(tcx.hir().definitions().def_index_count()),
             lazy_state: LazyState::NoNode,
             type_shorthands: Default::default(),
             predicate_shorthands: Default::default(),
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 6ae20a9d438..dffc8f33b2d 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -1,4 +1,4 @@
-use crate::table::Table;
+use crate::table::PerDefTable;
 
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
@@ -162,6 +162,7 @@ crate enum LazyState {
 // Only needed when `T` itself contains a parameter (e.g. `'tcx`).
 macro_rules! Lazy {
     (Table<$T:ty>) => {Lazy<Table<$T>, usize>};
+    (PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>};
     ([$T:ty]) => {Lazy<[$T], usize>};
     ($T:ty) => {Lazy<$T, ()>};
 }
@@ -196,7 +197,7 @@ crate struct CrateRoot<'tcx> {
     pub exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
     pub interpret_alloc_index: Lazy<[u32]>,
 
-    pub entries_table: Lazy!(Table<Entry<'tcx>>),
+    pub entries_table: Lazy!(PerDefTable<Entry<'tcx>>),
 
     /// The DefIndex's of any proc macros delcared by
     /// this crate
diff --git a/src/librustc_metadata/table.rs b/src/librustc_metadata/table.rs
index e18535060e6..c60c8e2cbce 100644
--- a/src/librustc_metadata/table.rs
+++ b/src/librustc_metadata/table.rs
@@ -73,44 +73,41 @@ impl FixedSizeEncoding for u32 {
 /// (e.g. while visiting the definitions of a crate), and on-demand decoding
 /// of specific indices (e.g. queries for per-definition data).
 /// Similar to `Vec<Lazy<T>>`, but with zero-copy decoding.
+// FIXME(eddyb) newtype `[u8]` 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.
 crate struct Table<T: LazyMeta<Meta = ()>> {
-    positions: Vec<u8>,
+    bytes: Vec<u8>,
     _marker: PhantomData<T>,
 }
 
 impl<T: LazyMeta<Meta = ()>> Table<T> {
-    crate fn new(max_index: usize) -> Self {
+    crate fn new(len: usize) -> Self {
         Table {
-            positions: vec![0; max_index * 4],
+            bytes: vec![0; len * 4],
             _marker: PhantomData,
         }
     }
 
-    crate fn record(&mut self, def_id: DefId, entry: Lazy<T>) {
-        assert!(def_id.is_local());
-        self.record_index(def_id.index, entry);
-    }
-
-    crate fn record_index(&mut self, item: DefIndex, entry: Lazy<T>) {
+    crate fn record(&mut self, i: usize, entry: Lazy<T>) {
         let position: u32 = entry.position.get().try_into().unwrap();
-        let array_index = item.index();
 
-        let positions = &mut self.positions;
-        assert!(u32::read_from_bytes_at(positions, array_index) == 0,
-                "recorded position for item {:?} twice, first at {:?} and now at {:?}",
-                item,
-                u32::read_from_bytes_at(positions, array_index),
+        assert!(u32::read_from_bytes_at(&self.bytes, i) == 0,
+                "recorded position for index {:?} twice, first at {:?} and now at {:?}",
+                i,
+                u32::read_from_bytes_at(&self.bytes, i),
                 position);
 
-        position.write_to_bytes_at(positions, array_index)
+        position.write_to_bytes_at(&mut self.bytes, i)
     }
 
     crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
         let pos = buf.position();
-        buf.emit_raw_bytes(&self.positions);
+        buf.emit_raw_bytes(&self.bytes);
         Lazy::from_position_and_meta(
             NonZeroUsize::new(pos as usize).unwrap(),
-            self.positions.len() / 4,
+            self.bytes.len(),
         )
     }
 }
@@ -119,22 +116,62 @@ impl<T: LazyMeta<Meta = ()>> LazyMeta for Table<T> {
     type Meta = usize;
 
     fn min_size(len: usize) -> usize {
-        len * 4
+        len
     }
 }
 
 impl<T: Encodable> Lazy<Table<T>> {
-    /// Given the metadata, extract out the offset of a particular
-    /// DefIndex (if any).
+    /// Given the metadata, extract out the offset of a particular index (if any).
     #[inline(never)]
-    crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<T>> {
-        debug!("Table::lookup: index={:?} len={:?}",
-               def_index,
-               self.meta);
+    crate fn lookup(&self, bytes: &[u8], i: usize) -> Option<Lazy<T>> {
+        debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
 
-        let bytes = &bytes[self.position.get()..][..self.meta * 4];
-        let position = u32::read_from_bytes_at(bytes, def_index.index());
+        let bytes = &bytes[self.position.get()..][..self.meta];
+        let position = u32::read_from_bytes_at(bytes, i);
         debug!("Table::lookup: position={:?}", position);
+
         NonZeroUsize::new(position as usize).map(Lazy::from_position)
     }
 }
+
+
+/// Per-definition table, similar to `Table` but keyed on `DefIndex`.
+// FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
+// and by using `newtype_index!` to define `DefIndex`.
+crate struct PerDefTable<T: LazyMeta<Meta = ()>>(Table<T>);
+
+impl<T: LazyMeta<Meta = ()>> PerDefTable<T> {
+    crate fn new(def_index_count: usize) -> Self {
+        PerDefTable(Table::new(def_index_count))
+    }
+
+    crate fn record(&mut self, def_id: DefId, entry: Lazy<T>) {
+        assert!(def_id.is_local());
+        self.0.record(def_id.index.index(), entry);
+    }
+
+    crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+        let lazy = self.0.encode(buf);
+        Lazy::from_position_and_meta(lazy.position, lazy.meta)
+    }
+}
+
+impl<T: LazyMeta<Meta = ()>> LazyMeta for PerDefTable<T> {
+    type Meta = <Table<T> as LazyMeta>::Meta;
+
+    fn min_size(meta: Self::Meta) -> usize {
+        Table::<T>::min_size(meta)
+    }
+}
+
+impl<T: Encodable> Lazy<PerDefTable<T>> {
+    fn as_table(&self) -> Lazy<Table<T>> {
+        Lazy::from_position_and_meta(self.position, self.meta)
+    }
+
+    /// Given the metadata, extract out the offset of a particular DefIndex (if any).
+    #[inline(never)]
+    crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<T>> {
+        self.as_table().lookup(bytes, def_index.index())
+    }
+}