Skip to content

Commit 5d52a7e

Browse files
committed
rustc_metadata: split tables into an usize-keyed Table and a DefIndex-keyed PerDefTable.
1 parent dd1264e commit 5d52a7e

File tree

4 files changed

+75
-37
lines changed

4 files changed

+75
-37
lines changed

src/librustc_metadata/decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::cstore::{self, CrateMetadata, MetadataBlob};
44
use crate::schema::*;
5-
use crate::table::Table;
5+
use crate::table::PerDefTable;
66

77
use rustc_index::vec::IndexVec;
88
use rustc_data_structures::sync::{Lrc, ReadGuard};
@@ -255,10 +255,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a,
255255
}
256256
}
257257

258-
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<Table<T>>> for DecodeContext<'a, 'tcx>
258+
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx>
259259
where T: LazyMeta<Meta = ()>,
260260
{
261-
fn specialized_decode(&mut self) -> Result<Lazy<Table<T>>, Self::Error> {
261+
fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> {
262262
let len = self.read_usize()?;
263263
self.read_lazy_with_meta(len)
264264
}

src/librustc_metadata/encoder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::schema::*;
2-
use crate::table::Table;
2+
use crate::table::PerDefTable;
33

44
use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
55
EncodedMetadata, ForeignModule};
@@ -47,7 +47,7 @@ struct EncodeContext<'tcx> {
4747
opaque: opaque::Encoder,
4848
tcx: TyCtxt<'tcx>,
4949

50-
entries_table: Table<Entry<'tcx>>,
50+
entries_table: PerDefTable<Entry<'tcx>>,
5151

5252
lazy_state: LazyState,
5353
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -114,10 +114,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
114114
}
115115
}
116116

117-
impl<'tcx, T> SpecializedEncoder<Lazy<Table<T>>> for EncodeContext<'tcx>
117+
impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx>
118118
where T: LazyMeta<Meta = ()>,
119119
{
120-
fn specialized_encode(&mut self, lazy: &Lazy<Table<T>>) -> Result<(), Self::Error> {
120+
fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> {
121121
self.emit_usize(lazy.meta)?;
122122
self.emit_lazy_distance(*lazy)
123123
}
@@ -1925,7 +1925,7 @@ crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
19251925
let mut ecx = EncodeContext {
19261926
opaque: encoder,
19271927
tcx,
1928-
entries_table: Table::new(tcx.hir().definitions().def_index_count()),
1928+
entries_table: PerDefTable::new(tcx.hir().definitions().def_index_count()),
19291929
lazy_state: LazyState::NoNode,
19301930
type_shorthands: Default::default(),
19311931
predicate_shorthands: Default::default(),

src/librustc_metadata/schema.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::table::Table;
1+
use crate::table::PerDefTable;
22

33
use rustc::hir;
44
use rustc::hir::def::{self, CtorKind};
@@ -162,6 +162,7 @@ crate enum LazyState {
162162
// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
163163
macro_rules! Lazy {
164164
(Table<$T:ty>) => {Lazy<Table<$T>, usize>};
165+
(PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>};
165166
([$T:ty]) => {Lazy<[$T], usize>};
166167
($T:ty) => {Lazy<$T, ()>};
167168
}
@@ -196,7 +197,7 @@ crate struct CrateRoot<'tcx> {
196197
pub exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
197198
pub interpret_alloc_index: Lazy<[u32]>,
198199

199-
pub entries_table: Lazy!(Table<Entry<'tcx>>),
200+
pub entries_table: Lazy!(PerDefTable<Entry<'tcx>>),
200201

201202
/// The DefIndex's of any proc macros delcared by
202203
/// this crate

src/librustc_metadata/table.rs

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,44 +73,41 @@ impl FixedSizeEncoding for u32 {
7373
/// (e.g. while visiting the definitions of a crate), and on-demand decoding
7474
/// of specific indices (e.g. queries for per-definition data).
7575
/// Similar to `Vec<Lazy<T>>`, but with zero-copy decoding.
76+
// FIXME(eddyb) newtype `[u8]` here, such that `Box<Table<T>>` would be used
77+
// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
78+
// Sadly, that doesn't work for `DefPerTable`, which is `(Table<T>, Table<T>)`,
79+
// and so would need two lengths in its metadata, which is not supported yet.
7680
crate struct Table<T: LazyMeta<Meta = ()>> {
77-
positions: Vec<u8>,
81+
bytes: Vec<u8>,
7882
_marker: PhantomData<T>,
7983
}
8084

8185
impl<T: LazyMeta<Meta = ()>> Table<T> {
82-
crate fn new(max_index: usize) -> Self {
86+
crate fn new(len: usize) -> Self {
8387
Table {
84-
positions: vec![0; max_index * 4],
88+
bytes: vec![0; len * 4],
8589
_marker: PhantomData,
8690
}
8791
}
8892

89-
crate fn record(&mut self, def_id: DefId, entry: Lazy<T>) {
90-
assert!(def_id.is_local());
91-
self.record_index(def_id.index, entry);
92-
}
93-
94-
crate fn record_index(&mut self, item: DefIndex, entry: Lazy<T>) {
93+
crate fn record(&mut self, i: usize, entry: Lazy<T>) {
9594
let position: u32 = entry.position.get().try_into().unwrap();
96-
let array_index = item.index();
9795

98-
let positions = &mut self.positions;
99-
assert!(u32::read_from_bytes_at(positions, array_index) == 0,
100-
"recorded position for item {:?} twice, first at {:?} and now at {:?}",
101-
item,
102-
u32::read_from_bytes_at(positions, array_index),
96+
assert!(u32::read_from_bytes_at(&self.bytes, i) == 0,
97+
"recorded position for index {:?} twice, first at {:?} and now at {:?}",
98+
i,
99+
u32::read_from_bytes_at(&self.bytes, i),
103100
position);
104101

105-
position.write_to_bytes_at(positions, array_index)
102+
position.write_to_bytes_at(&mut self.bytes, i)
106103
}
107104

108105
crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
109106
let pos = buf.position();
110-
buf.emit_raw_bytes(&self.positions);
107+
buf.emit_raw_bytes(&self.bytes);
111108
Lazy::from_position_and_meta(
112109
NonZeroUsize::new(pos as usize).unwrap(),
113-
self.positions.len() / 4,
110+
self.bytes.len(),
114111
)
115112
}
116113
}
@@ -119,22 +116,62 @@ impl<T: LazyMeta<Meta = ()>> LazyMeta for Table<T> {
119116
type Meta = usize;
120117

121118
fn min_size(len: usize) -> usize {
122-
len * 4
119+
len
123120
}
124121
}
125122

126123
impl<T: Encodable> Lazy<Table<T>> {
127-
/// Given the metadata, extract out the offset of a particular
128-
/// DefIndex (if any).
124+
/// Given the metadata, extract out the offset of a particular index (if any).
129125
#[inline(never)]
130-
crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<T>> {
131-
debug!("Table::lookup: index={:?} len={:?}",
132-
def_index,
133-
self.meta);
126+
crate fn lookup(&self, bytes: &[u8], i: usize) -> Option<Lazy<T>> {
127+
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
134128

135-
let bytes = &bytes[self.position.get()..][..self.meta * 4];
136-
let position = u32::read_from_bytes_at(bytes, def_index.index());
129+
let bytes = &bytes[self.position.get()..][..self.meta];
130+
let position = u32::read_from_bytes_at(bytes, i);
137131
debug!("Table::lookup: position={:?}", position);
132+
138133
NonZeroUsize::new(position as usize).map(Lazy::from_position)
139134
}
140135
}
136+
137+
138+
/// Per-definition table, similar to `Table` but keyed on `DefIndex`.
139+
// FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
140+
// and by using `newtype_index!` to define `DefIndex`.
141+
crate struct PerDefTable<T: LazyMeta<Meta = ()>>(Table<T>);
142+
143+
impl<T: LazyMeta<Meta = ()>> PerDefTable<T> {
144+
crate fn new(def_index_count: usize) -> Self {
145+
PerDefTable(Table::new(def_index_count))
146+
}
147+
148+
crate fn record(&mut self, def_id: DefId, entry: Lazy<T>) {
149+
assert!(def_id.is_local());
150+
self.0.record(def_id.index.index(), entry);
151+
}
152+
153+
crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
154+
let lazy = self.0.encode(buf);
155+
Lazy::from_position_and_meta(lazy.position, lazy.meta)
156+
}
157+
}
158+
159+
impl<T: LazyMeta<Meta = ()>> LazyMeta for PerDefTable<T> {
160+
type Meta = <Table<T> as LazyMeta>::Meta;
161+
162+
fn min_size(meta: Self::Meta) -> usize {
163+
Table::<T>::min_size(meta)
164+
}
165+
}
166+
167+
impl<T: Encodable> Lazy<PerDefTable<T>> {
168+
fn as_table(&self) -> Lazy<Table<T>> {
169+
Lazy::from_position_and_meta(self.position, self.meta)
170+
}
171+
172+
/// Given the metadata, extract out the offset of a particular DefIndex (if any).
173+
#[inline(never)]
174+
crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<T>> {
175+
self.as_table().lookup(bytes, def_index.index())
176+
}
177+
}

0 commit comments

Comments
 (0)