rustc_metadata: split tables into an usize-keyed Table and a DefIndex-keyed PerDefTable.
This commit is contained in:
parent
dd1264e90a
commit
5d52a7e0d0
@ -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)
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user