Rollup merge of #66399 - eddyb:rmeta-table-cleanup, r=Mark-Simulacrum
rustc_metadata: simplify the interactions between Lazy and Table. These are small post-#59953 cleanups (including undoing some contrivances from that PR). r? @michaelwoerister
This commit is contained in:
commit
5139b53836
4 changed files with 99 additions and 161 deletions
|
@ -1,9 +1,9 @@
|
||||||
// Decoding metadata from a single crate's metadata
|
// Decoding metadata from a single crate's metadata
|
||||||
|
|
||||||
use crate::rmeta::*;
|
use crate::rmeta::*;
|
||||||
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
|
use crate::rmeta::table::{FixedSizeEncoding, Table};
|
||||||
|
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
|
use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
|
||||||
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
|
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
|
||||||
use rustc::hir::map::definitions::DefPathTable;
|
use rustc::hir::map::definitions::DefPathTable;
|
||||||
|
@ -32,7 +32,7 @@ use std::mem;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, SpecializedDecoder, opaque};
|
use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::ast::{self, Ident};
|
use syntax::ast::{self, Ident};
|
||||||
use syntax::source_map::{self, respan, Spanned};
|
use syntax::source_map::{self, respan, Spanned};
|
||||||
|
@ -217,7 +217,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
|
impl<'a, 'tcx, T: Decodable> Lazy<T> {
|
||||||
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
|
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
|
||||||
let mut dcx = metadata.decoder(self.position.get());
|
let mut dcx = metadata.decoder(self.position.get());
|
||||||
dcx.lazy_state = LazyState::NodeStart(self.position);
|
dcx.lazy_state = LazyState::NodeStart(self.position);
|
||||||
|
@ -225,7 +225,7 @@ impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> {
|
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
|
||||||
fn decode<M: Metadata<'a, 'tcx>>(
|
fn decode<M: Metadata<'a, 'tcx>>(
|
||||||
self,
|
self,
|
||||||
metadata: M,
|
metadata: M,
|
||||||
|
@ -324,13 +324,13 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
|
||||||
self.read_lazy_with_meta(())
|
self.read_lazy_with_meta(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
|
||||||
let len = self.read_usize()?;
|
let len = self.read_usize()?;
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
|
@ -341,10 +341,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx>
|
impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>>> for DecodeContext<'a, 'tcx>
|
||||||
where Option<T>: FixedSizeEncoding,
|
where Option<T>: FixedSizeEncoding,
|
||||||
{
|
{
|
||||||
fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<Lazy<Table<I, T>>, Self::Error> {
|
||||||
let len = self.read_usize()?;
|
let len = self.read_usize()?;
|
||||||
self.read_lazy_with_meta(len)
|
self.read_lazy_with_meta(len)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::rmeta::*;
|
use crate::rmeta::*;
|
||||||
use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
|
use crate::rmeta::table::FixedSizeEncoding;
|
||||||
|
|
||||||
use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
|
use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
|
||||||
EncodedMetadata, ForeignModule};
|
EncodedMetadata, ForeignModule};
|
||||||
|
@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId,
|
||||||
use rustc::hir::{GenericParamKind, AnonConst};
|
use rustc::hir::{GenericParamKind, AnonConst};
|
||||||
use rustc::hir::map::definitions::DefPathTable;
|
use rustc::hir::map::definitions::DefPathTable;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::Idx;
|
||||||
use rustc::middle::dependency_format::Linkage;
|
use rustc::middle::dependency_format::Linkage;
|
||||||
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
|
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
|
||||||
metadata_symbol_name};
|
metadata_symbol_name};
|
||||||
|
@ -47,7 +47,7 @@ struct EncodeContext<'tcx> {
|
||||||
opaque: opaque::Encoder,
|
opaque: opaque::Encoder,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
per_def: PerDefTables<'tcx>,
|
per_def: PerDefTableBuilders<'tcx>,
|
||||||
|
|
||||||
lazy_state: LazyState,
|
lazy_state: LazyState,
|
||||||
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
|
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
|
||||||
|
@ -60,30 +60,6 @@ struct EncodeContext<'tcx> {
|
||||||
source_file_cache: Lrc<SourceFile>,
|
source_file_cache: Lrc<SourceFile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct PerDefTables<'tcx> {
|
|
||||||
kind: PerDefTable<Lazy<EntryKind<'tcx>>>,
|
|
||||||
visibility: PerDefTable<Lazy<ty::Visibility>>,
|
|
||||||
span: PerDefTable<Lazy<Span>>,
|
|
||||||
attributes: PerDefTable<Lazy<[ast::Attribute]>>,
|
|
||||||
children: PerDefTable<Lazy<[DefIndex]>>,
|
|
||||||
stability: PerDefTable<Lazy<attr::Stability>>,
|
|
||||||
deprecation: PerDefTable<Lazy<attr::Deprecation>>,
|
|
||||||
|
|
||||||
ty: PerDefTable<Lazy<Ty<'tcx>>>,
|
|
||||||
fn_sig: PerDefTable<Lazy<ty::PolyFnSig<'tcx>>>,
|
|
||||||
impl_trait_ref: PerDefTable<Lazy<ty::TraitRef<'tcx>>>,
|
|
||||||
inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
|
|
||||||
variances: PerDefTable<Lazy<[ty::Variance]>>,
|
|
||||||
generics: PerDefTable<Lazy<ty::Generics>>,
|
|
||||||
explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
|
||||||
inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
|
|
||||||
super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
|
||||||
|
|
||||||
mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
|
|
||||||
promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! encoder_methods {
|
macro_rules! encoder_methods {
|
||||||
($($name:ident($ty:ty);)*) => {
|
($($name:ident($ty:ty);)*) => {
|
||||||
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
$(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
|
||||||
|
@ -122,13 +98,13 @@ impl<'tcx> Encoder for EncodeContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
|
impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
|
||||||
fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
|
||||||
self.emit_lazy_distance(*lazy)
|
self.emit_lazy_distance(*lazy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
|
impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
|
||||||
fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
|
||||||
self.emit_usize(lazy.meta)?;
|
self.emit_usize(lazy.meta)?;
|
||||||
if lazy.meta == 0 {
|
if lazy.meta == 0 {
|
||||||
|
@ -138,10 +114,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx>
|
impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>>> for EncodeContext<'tcx>
|
||||||
where Option<T>: FixedSizeEncoding,
|
where Option<T>: FixedSizeEncoding,
|
||||||
{
|
{
|
||||||
fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, lazy: &Lazy<Table<I, T>>) -> Result<(), Self::Error> {
|
||||||
self.emit_usize(lazy.meta)?;
|
self.emit_usize(lazy.meta)?;
|
||||||
self.emit_lazy_distance(*lazy)
|
self.emit_lazy_distance(*lazy)
|
||||||
}
|
}
|
||||||
|
@ -307,14 +283,14 @@ impl<I, T: Encodable> EncodeContentsForLazy<[T]> for I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shorthand for `$self.$tables.$table.set($key, $self.lazy($value))`, which would
|
// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy($value))`, which would
|
||||||
// normally need extra variables to avoid errors about multiple mutable borrows.
|
// normally need extra variables to avoid errors about multiple mutable borrows.
|
||||||
macro_rules! record {
|
macro_rules! record {
|
||||||
($self:ident.$tables:ident.$table:ident[$key:expr] <- $value:expr) => {{
|
($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
|
||||||
{
|
{
|
||||||
let value = $value;
|
let value = $value;
|
||||||
let lazy = $self.lazy(value);
|
let lazy = $self.lazy(value);
|
||||||
$self.$tables.$table.set($key, lazy);
|
$self.$tables.$table.set($def_id.index, lazy);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -509,28 +485,7 @@ impl<'tcx> EncodeContext<'tcx> {
|
||||||
|
|
||||||
|
|
||||||
i = self.position();
|
i = self.position();
|
||||||
let per_def = LazyPerDefTables {
|
let per_def = self.per_def.encode(&mut self.opaque);
|
||||||
kind: self.per_def.kind.encode(&mut self.opaque),
|
|
||||||
visibility: self.per_def.visibility.encode(&mut self.opaque),
|
|
||||||
span: self.per_def.span.encode(&mut self.opaque),
|
|
||||||
attributes: self.per_def.attributes.encode(&mut self.opaque),
|
|
||||||
children: self.per_def.children.encode(&mut self.opaque),
|
|
||||||
stability: self.per_def.stability.encode(&mut self.opaque),
|
|
||||||
deprecation: self.per_def.deprecation.encode(&mut self.opaque),
|
|
||||||
|
|
||||||
ty: self.per_def.ty.encode(&mut self.opaque),
|
|
||||||
fn_sig: self.per_def.fn_sig.encode(&mut self.opaque),
|
|
||||||
impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque),
|
|
||||||
inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
|
|
||||||
variances: self.per_def.variances.encode(&mut self.opaque),
|
|
||||||
generics: self.per_def.generics.encode(&mut self.opaque),
|
|
||||||
explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque),
|
|
||||||
inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque),
|
|
||||||
super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
|
|
||||||
|
|
||||||
mir: self.per_def.mir.encode(&mut self.opaque),
|
|
||||||
promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque),
|
|
||||||
};
|
|
||||||
let per_def_bytes = self.position() - i;
|
let per_def_bytes = self.position() - i;
|
||||||
|
|
||||||
// Encode the proc macro data
|
// Encode the proc macro data
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use decoder::Metadata;
|
use decoder::Metadata;
|
||||||
use table::PerDefTable;
|
use table::{Table, TableBuilder};
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def::{self, CtorKind};
|
use rustc::hir::def::{self, CtorKind};
|
||||||
|
@ -15,7 +15,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_data_structures::sync::MetadataRef;
|
use rustc_data_structures::sync::MetadataRef;
|
||||||
use rustc_serialize::Encodable;
|
use rustc_serialize::opaque::Encoder;
|
||||||
use syntax::{ast, attr};
|
use syntax::{ast, attr};
|
||||||
use syntax::edition::Edition;
|
use syntax::edition::Edition;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
|
@ -59,7 +59,7 @@ trait LazyMeta {
|
||||||
fn min_size(meta: Self::Meta) -> usize;
|
fn min_size(meta: Self::Meta) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encodable> LazyMeta for T {
|
impl<T> LazyMeta for T {
|
||||||
type Meta = ();
|
type Meta = ();
|
||||||
|
|
||||||
fn min_size(_: ()) -> usize {
|
fn min_size(_: ()) -> usize {
|
||||||
|
@ -68,7 +68,7 @@ impl<T: Encodable> LazyMeta for T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encodable> LazyMeta for [T] {
|
impl<T> LazyMeta for [T] {
|
||||||
type Meta = usize;
|
type Meta = usize;
|
||||||
|
|
||||||
fn min_size(len: usize) -> usize {
|
fn min_size(len: usize) -> usize {
|
||||||
|
@ -124,13 +124,13 @@ impl<T: ?Sized + LazyMeta> Lazy<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encodable> Lazy<T> {
|
impl<T> Lazy<T> {
|
||||||
fn from_position(position: NonZeroUsize) -> Lazy<T> {
|
fn from_position(position: NonZeroUsize) -> Lazy<T> {
|
||||||
Lazy::from_position_and_meta(position, ())
|
Lazy::from_position_and_meta(position, ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encodable> Lazy<[T]> {
|
impl<T> Lazy<[T]> {
|
||||||
fn empty() -> Lazy<[T]> {
|
fn empty() -> Lazy<[T]> {
|
||||||
Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
|
Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,7 @@ enum LazyState {
|
||||||
// manually, instead of relying on the default, to get the correct variance.
|
// manually, instead of relying on the default, to get the correct variance.
|
||||||
// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
|
// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
|
||||||
macro_rules! Lazy {
|
macro_rules! Lazy {
|
||||||
(Table<$T:ty>) => {Lazy<Table<$T>, usize>};
|
(Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
|
||||||
(PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>};
|
|
||||||
([$T:ty]) => {Lazy<[$T], usize>};
|
([$T:ty]) => {Lazy<[$T], usize>};
|
||||||
($T:ty) => {Lazy<$T, ()>};
|
($T:ty) => {Lazy<$T, ()>};
|
||||||
}
|
}
|
||||||
|
@ -232,31 +231,53 @@ crate struct TraitImpls {
|
||||||
impls: Lazy<[DefIndex]>,
|
impls: Lazy<[DefIndex]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time.
|
||||||
crate struct LazyPerDefTables<'tcx> {
|
macro_rules! define_per_def_tables {
|
||||||
kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
|
($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
|
||||||
visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
span: Lazy!(PerDefTable<Lazy<Span>>),
|
crate struct LazyPerDefTables<'tcx> {
|
||||||
attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
|
$($name: Lazy!(Table<DefIndex, $T>)),+
|
||||||
children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
|
}
|
||||||
stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
|
|
||||||
deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
|
#[derive(Default)]
|
||||||
ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
|
struct PerDefTableBuilders<'tcx> {
|
||||||
fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
|
$($name: TableBuilder<DefIndex, $T>),+
|
||||||
impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
|
}
|
||||||
inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
|
|
||||||
variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
|
impl PerDefTableBuilders<'tcx> {
|
||||||
generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
|
fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> {
|
||||||
explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
LazyPerDefTables {
|
||||||
|
$($name: self.$name.encode(buf)),+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_per_def_tables! {
|
||||||
|
kind: Table<DefIndex, Lazy!(EntryKind<'tcx>)>,
|
||||||
|
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
|
||||||
|
span: Table<DefIndex, Lazy<Span>>,
|
||||||
|
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
|
||||||
|
children: Table<DefIndex, Lazy<[DefIndex]>>,
|
||||||
|
stability: Table<DefIndex, Lazy<attr::Stability>>,
|
||||||
|
deprecation: Table<DefIndex, Lazy<attr::Deprecation>>,
|
||||||
|
ty: Table<DefIndex, Lazy!(Ty<'tcx>)>,
|
||||||
|
fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
|
||||||
|
impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>,
|
||||||
|
inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
|
||||||
|
variances: Table<DefIndex, Lazy<[ty::Variance]>>,
|
||||||
|
generics: Table<DefIndex, Lazy<ty::Generics>>,
|
||||||
|
explicit_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
|
||||||
// FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
|
// FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
|
||||||
// doesn't handle shorthands in its own (de)serialization impls,
|
// doesn't handle shorthands in its own (de)serialization impls,
|
||||||
// as it's an `enum` for which we want to derive (de)serialization,
|
// as it's an `enum` for which we want to derive (de)serialization,
|
||||||
// so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
|
// so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
|
||||||
// Also, as an optimization, a missing entry indicates an empty `&[]`.
|
// Also, as an optimization, a missing entry indicates an empty `&[]`.
|
||||||
inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
|
inferred_outlives: Table<DefIndex, Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>,
|
||||||
super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
|
||||||
mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
|
mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
|
||||||
promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
|
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::rmeta::*;
|
use crate::rmeta::*;
|
||||||
|
|
||||||
use rustc::hir::def_id::{DefId, DefIndex};
|
use rustc_index::vec::Idx;
|
||||||
use rustc_serialize::{Encodable, opaque::Encoder};
|
use rustc_serialize::{Encodable, opaque::Encoder};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -117,37 +117,46 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Random-access table (i.e. offeringconstant-time `get`/`set`), similar to
|
/// Random-access table (i.e. offering constant-time `get`/`set`), similar to
|
||||||
/// `Vec<Option<T>>`, but without requiring encoding or decoding all the values
|
/// `Vec<Option<T>>`, but without requiring encoding or decoding all the values
|
||||||
/// eagerly and in-order.
|
/// eagerly and in-order.
|
||||||
/// A total of `(max_idx + 1) * <Option<T> as FixedSizeEncoding>::BYTE_LEN` bytes
|
/// A total of `(max_idx + 1) * <Option<T> as FixedSizeEncoding>::BYTE_LEN` bytes
|
||||||
/// are used for a table, where `max_idx` is the largest index passed to `set`.
|
/// are used for a table, where `max_idx` is the largest index passed to
|
||||||
// FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
|
/// `TableBuilder::set`.
|
||||||
// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
|
pub(super) struct Table<I: Idx, T> where Option<T>: FixedSizeEncoding {
|
||||||
// (not sure if that is possible given that the `Vec` is being resized now)
|
_marker: PhantomData<(fn(&I), T)>,
|
||||||
pub(super) struct Table<T> where Option<T>: FixedSizeEncoding {
|
// NOTE(eddyb) this makes `Table` not implement `Sized`, but no
|
||||||
// FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
|
// value of `Table` is ever created (it's always behind `Lazy`).
|
||||||
// once that starts being allowed by the compiler (i.e. lazy normalization).
|
_bytes: [u8],
|
||||||
bytes: Vec<u8>,
|
|
||||||
_marker: PhantomData<T>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
|
/// Helper for constructing a table's serialization (also see `Table`).
|
||||||
|
pub(super) struct TableBuilder<I: Idx, T> where Option<T>: FixedSizeEncoding {
|
||||||
|
// FIXME(eddyb) use `IndexVec<I, [u8; <Option<T>>::BYTE_LEN]>` instead of
|
||||||
|
// `Vec<u8>`, once that starts working (i.e. lazy normalization).
|
||||||
|
// Then again, that has the downside of not allowing `TableBuilder::encode` to
|
||||||
|
// obtain a `&[u8]` entirely in safe code, for writing the bytes out.
|
||||||
|
bytes: Vec<u8>,
|
||||||
|
_marker: PhantomData<(fn(&I), T)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Idx, T> Default for TableBuilder<I, T> where Option<T>: FixedSizeEncoding {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Table {
|
TableBuilder {
|
||||||
bytes: vec![],
|
bytes: vec![],
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Table<T> where Option<T>: FixedSizeEncoding {
|
impl<I: Idx, T> TableBuilder<I, T> where Option<T>: FixedSizeEncoding {
|
||||||
fn set(&mut self, i: usize, value: T) {
|
pub(super) fn set(&mut self, i: I, value: T) {
|
||||||
// FIXME(eddyb) investigate more compact encodings for sparse tables.
|
// FIXME(eddyb) investigate more compact encodings for sparse tables.
|
||||||
// On the PR @michaelwoerister mentioned:
|
// On the PR @michaelwoerister mentioned:
|
||||||
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
|
// > Space requirements could perhaps be optimized by using the HAMT `popcnt`
|
||||||
// > trick (i.e. divide things into buckets of 32 or 64 items and then
|
// > trick (i.e. divide things into buckets of 32 or 64 items and then
|
||||||
// > store bit-masks of which item in each bucket is actually serialized).
|
// > store bit-masks of which item in each bucket is actually serialized).
|
||||||
|
let i = i.index();
|
||||||
let needed = (i + 1) * <Option<T>>::BYTE_LEN;
|
let needed = (i + 1) * <Option<T>>::BYTE_LEN;
|
||||||
if self.bytes.len() < needed {
|
if self.bytes.len() < needed {
|
||||||
self.bytes.resize(needed, 0);
|
self.bytes.resize(needed, 0);
|
||||||
|
@ -156,7 +165,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
|
||||||
Some(value).write_to_bytes_at(&mut self.bytes, i);
|
Some(value).write_to_bytes_at(&mut self.bytes, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
|
pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> {
|
||||||
let pos = buf.position();
|
let pos = buf.position();
|
||||||
buf.emit_raw_bytes(&self.bytes);
|
buf.emit_raw_bytes(&self.bytes);
|
||||||
Lazy::from_position_and_meta(
|
Lazy::from_position_and_meta(
|
||||||
|
@ -166,7 +175,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
|
impl<I: Idx, T> LazyMeta for Table<I, T> where Option<T>: FixedSizeEncoding {
|
||||||
type Meta = usize;
|
type Meta = usize;
|
||||||
|
|
||||||
fn min_size(len: usize) -> usize {
|
fn min_size(len: usize) -> usize {
|
||||||
|
@ -174,65 +183,18 @@ impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
|
impl<I: Idx, T> Lazy<Table<I, T>> where Option<T>: FixedSizeEncoding {
|
||||||
/// Given the metadata, extract out the value at a particular index (if any).
|
/// Given the metadata, extract out the value at a particular index (if any).
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
|
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
metadata: M,
|
metadata: M,
|
||||||
i: usize,
|
i: I,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
|
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
|
||||||
|
|
||||||
let start = self.position.get();
|
let start = self.position.get();
|
||||||
let bytes = &metadata.raw_bytes()[start..start + self.meta];
|
let bytes = &metadata.raw_bytes()[start..start + self.meta];
|
||||||
<Option<T>>::maybe_read_from_bytes_at(bytes, i)?
|
<Option<T>>::maybe_read_from_bytes_at(bytes, i.index())?
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Like a `Table` but using `DefIndex` instead of `usize` as keys.
|
|
||||||
// FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
|
|
||||||
// and by using `newtype_index!` to define `DefIndex`.
|
|
||||||
pub(super) struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
|
|
||||||
|
|
||||||
impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
|
|
||||||
fn default() -> Self {
|
|
||||||
PerDefTable(Table::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
|
|
||||||
pub(super) fn set(&mut self, def_id: DefId, value: T) {
|
|
||||||
assert!(def_id.is_local());
|
|
||||||
self.0.set(def_id.index.index(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) 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 for PerDefTable<T> where Option<T>: FixedSizeEncoding {
|
|
||||||
type Meta = <Table<T> as LazyMeta>::Meta;
|
|
||||||
|
|
||||||
fn min_size(meta: Self::Meta) -> usize {
|
|
||||||
Table::<T>::min_size(meta)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding {
|
|
||||||
fn as_table(&self) -> Lazy<Table<T>> {
|
|
||||||
Lazy::from_position_and_meta(self.position, self.meta)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given the metadata, extract out the value at a particular DefIndex (if any).
|
|
||||||
#[inline(never)]
|
|
||||||
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
|
|
||||||
&self,
|
|
||||||
metadata: M,
|
|
||||||
def_index: DefIndex,
|
|
||||||
) -> Option<T> {
|
|
||||||
self.as_table().get(metadata, def_index.index())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue