Cache decoded predicate shorthands
This commit is contained in:
parent
228a0ed7b0
commit
8ea55f1a99
5 changed files with 118 additions and 71 deletions
|
@ -294,15 +294,36 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
|
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
|
||||||
|
|
||||||
if let Some(&ty) = tcx.rcache.borrow().get(&key) {
|
if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) {
|
||||||
return Ok(ty);
|
return Ok(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = or_insert_with(self)?;
|
let ty = or_insert_with(self)?;
|
||||||
tcx.rcache.borrow_mut().insert(key, ty);
|
tcx.ty_rcache.borrow_mut().insert(key, ty);
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cached_predicate_for_shorthand<F>(
|
||||||
|
&mut self,
|
||||||
|
shorthand: usize,
|
||||||
|
or_insert_with: F,
|
||||||
|
) -> Result<ty::Predicate<'tcx>, Self::Error>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
|
||||||
|
{
|
||||||
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
|
||||||
|
|
||||||
|
if let Some(&pred) = tcx.pred_rcache.borrow().get(&key) {
|
||||||
|
return Ok(pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pred = or_insert_with(self)?;
|
||||||
|
tcx.pred_rcache.borrow_mut().insert(key, pred);
|
||||||
|
Ok(pred)
|
||||||
|
}
|
||||||
|
|
||||||
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
|
|
|
@ -239,6 +239,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b, 'tcx> SpecializedEncoder<ty::Predicate<'b>> for EncodeContext<'tcx> {
|
||||||
|
fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
|
||||||
|
debug_assert!(self.tcx.lift(predicate).is_some());
|
||||||
|
let predicate =
|
||||||
|
unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
|
||||||
|
ty_codec::encode_with_shorthand(self, predicate, |encoder| {
|
||||||
|
&mut encoder.predicate_shorthands
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
|
impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
|
||||||
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
@ -256,22 +267,6 @@ impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'tcx> SpecializedEncoder<&'a [(ty::Predicate<'b>, Span)]> for EncodeContext<'tcx> {
|
|
||||||
fn specialized_encode(
|
|
||||||
&mut self,
|
|
||||||
predicates: &&'a [(ty::Predicate<'b>, Span)],
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
debug_assert!(self.tcx.lift(*predicates).is_some());
|
|
||||||
let predicates = unsafe {
|
|
||||||
std::mem::transmute::<
|
|
||||||
&&'a [(ty::Predicate<'b>, Span)],
|
|
||||||
&&'tcx [(ty::Predicate<'tcx>, Span)],
|
|
||||||
>(predicates)
|
|
||||||
};
|
|
||||||
ty_codec::encode_spanned_predicates(self, &predicates, |ecx| &mut ecx.predicate_shorthands)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'tcx> {
|
impl<'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'tcx> {
|
||||||
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
|
||||||
f.encode_opaque(&mut self.opaque)
|
f.encode_opaque(&mut self.opaque)
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::arena::ArenaAllocatable;
|
||||||
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
|
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
|
||||||
use crate::mir::{self, interpret::Allocation};
|
use crate::mir::{self, interpret::Allocation};
|
||||||
use crate::ty::subst::SubstsRef;
|
use crate::ty::subst::SubstsRef;
|
||||||
use crate::ty::{self, List, ToPredicate, Ty, TyCtxt};
|
use crate::ty::{self, List, Ty, TyCtxt};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::{CrateNum, DefId};
|
use rustc_hir::def_id::{CrateNum, DefId};
|
||||||
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
|
||||||
|
@ -95,23 +95,6 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode_spanned_predicates<'tcx, E, C>(
|
|
||||||
encoder: &mut E,
|
|
||||||
predicates: &[(ty::Predicate<'tcx>, Span)],
|
|
||||||
cache: C,
|
|
||||||
) -> Result<(), E::Error>
|
|
||||||
where
|
|
||||||
E: TyEncoder,
|
|
||||||
C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>,
|
|
||||||
{
|
|
||||||
predicates.len().encode(encoder)?;
|
|
||||||
for (predicate, span) in predicates {
|
|
||||||
encode_with_shorthand(encoder, predicate, &cache)?;
|
|
||||||
span.encode(encoder)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait TyDecoder<'tcx>: Decoder {
|
pub trait TyDecoder<'tcx>: Decoder {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
|
|
||||||
|
@ -127,6 +110,14 @@ pub trait TyDecoder<'tcx>: Decoder {
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
|
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
|
||||||
|
|
||||||
|
fn cached_predicate_for_shorthand<F>(
|
||||||
|
&mut self,
|
||||||
|
shorthand: usize,
|
||||||
|
or_insert_with: F,
|
||||||
|
) -> Result<ty::Predicate<'tcx>, Self::Error>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>;
|
||||||
|
|
||||||
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R;
|
F: FnOnce(&mut Self) -> R;
|
||||||
|
@ -188,6 +179,26 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn decode_predicate<D>(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error>
|
||||||
|
where
|
||||||
|
D: TyDecoder<'tcx>,
|
||||||
|
{
|
||||||
|
// Handle shorthands first, if we have an usize > 0x80.
|
||||||
|
if decoder.positioned_at_shorthand() {
|
||||||
|
let pos = decoder.read_usize()?;
|
||||||
|
assert!(pos >= SHORTHAND_OFFSET);
|
||||||
|
let shorthand = pos - SHORTHAND_OFFSET;
|
||||||
|
|
||||||
|
decoder.cached_predicate_for_shorthand(shorthand, |decoder| {
|
||||||
|
decoder.with_position(shorthand, ty::Predicate::decode)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let tcx = decoder.tcx();
|
||||||
|
Ok(tcx.mk_predicate(ty::PredicateKind::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn decode_spanned_predicates<D>(
|
pub fn decode_spanned_predicates<D>(
|
||||||
decoder: &mut D,
|
decoder: &mut D,
|
||||||
|
@ -198,20 +209,7 @@ where
|
||||||
let tcx = decoder.tcx();
|
let tcx = decoder.tcx();
|
||||||
Ok(tcx.arena.alloc_from_iter(
|
Ok(tcx.arena.alloc_from_iter(
|
||||||
(0..decoder.read_usize()?)
|
(0..decoder.read_usize()?)
|
||||||
.map(|_| {
|
.map(|_| Decodable::decode(decoder))
|
||||||
// Handle shorthands first, if we have an usize > 0x80.
|
|
||||||
let predicate_kind = if decoder.positioned_at_shorthand() {
|
|
||||||
let pos = decoder.read_usize()?;
|
|
||||||
assert!(pos >= SHORTHAND_OFFSET);
|
|
||||||
let shorthand = pos - SHORTHAND_OFFSET;
|
|
||||||
|
|
||||||
decoder.with_position(shorthand, ty::PredicateKind::decode)
|
|
||||||
} else {
|
|
||||||
ty::PredicateKind::decode(decoder)
|
|
||||||
}?;
|
|
||||||
let predicate = predicate_kind.to_predicate(tcx);
|
|
||||||
Ok((predicate, Decodable::decode(decoder)?))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -421,7 +419,6 @@ macro_rules! implement_ty_decoder {
|
||||||
// FIXME(#36588): These impls are horribly unsound as they allow
|
// FIXME(#36588): These impls are horribly unsound as they allow
|
||||||
// the caller to pick any lifetime for `'tcx`, including `'static`.
|
// the caller to pick any lifetime for `'tcx`, including `'static`.
|
||||||
|
|
||||||
rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
|
|
||||||
arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
|
arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
|
||||||
|
|
||||||
impl<$($typaram),*> SpecializedDecoder<CrateNum>
|
impl<$($typaram),*> SpecializedDecoder<CrateNum>
|
||||||
|
@ -436,7 +433,24 @@ macro_rules! implement_ty_decoder {
|
||||||
where &'_x ty::TyS<'_y>: UseSpecializedDecodable
|
where &'_x ty::TyS<'_y>: UseSpecializedDecodable
|
||||||
{
|
{
|
||||||
fn specialized_decode(&mut self) -> Result<&'_x ty::TyS<'_y>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<&'_x ty::TyS<'_y>, Self::Error> {
|
||||||
unsafe { transmute::<Result<ty::Ty<'tcx>, Self::Error>, Result<&'_x ty::TyS<'_y>, Self::Error>>(decode_ty(self)) }
|
unsafe {
|
||||||
|
transmute::<
|
||||||
|
Result<ty::Ty<'tcx>, Self::Error>,
|
||||||
|
Result<&'_x ty::TyS<'_y>, Self::Error>,
|
||||||
|
>(decode_ty(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'_x, $($typaram),*> SpecializedDecoder<ty::Predicate<'_x>>
|
||||||
|
for $DecoderName<$($typaram),*> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<ty::Predicate<'_x>, Self::Error> {
|
||||||
|
unsafe {
|
||||||
|
transmute::<
|
||||||
|
Result<ty::Predicate<'tcx>, Self::Error>,
|
||||||
|
Result<ty::Predicate<'_x>, Self::Error>,
|
||||||
|
>(decode_predicate(self))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -938,8 +938,9 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
/// via `extern crate` item and not `--extern` option or compiler built-in.
|
/// via `extern crate` item and not `--extern` option or compiler built-in.
|
||||||
pub extern_prelude: FxHashMap<Symbol, bool>,
|
pub extern_prelude: FxHashMap<Symbol, bool>,
|
||||||
|
|
||||||
// Internal cache for metadata decoding. No need to track deps on this.
|
// Internal caches for metadata decoding. No need to track deps on this.
|
||||||
pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
|
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
|
||||||
|
pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
|
||||||
|
|
||||||
/// Caches the results of trait selection. This cache is used
|
/// Caches the results of trait selection. This cache is used
|
||||||
/// for things that do not have to do with the parameters in scope.
|
/// for things that do not have to do with the parameters in scope.
|
||||||
|
@ -1128,7 +1129,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
definitions,
|
definitions,
|
||||||
def_path_hash_to_def_id,
|
def_path_hash_to_def_id,
|
||||||
queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache),
|
queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache),
|
||||||
rcache: Default::default(),
|
ty_rcache: Default::default(),
|
||||||
|
pred_rcache: Default::default(),
|
||||||
selection_cache: Default::default(),
|
selection_cache: Default::default(),
|
||||||
evaluation_cache: Default::default(),
|
evaluation_cache: Default::default(),
|
||||||
crate_name: Symbol::intern(crate_name),
|
crate_name: Symbol::intern(crate_name),
|
||||||
|
|
|
@ -524,16 +524,39 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
|
||||||
let cache_key =
|
let cache_key =
|
||||||
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
|
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
|
||||||
|
|
||||||
if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
|
if let Some(&ty) = tcx.ty_rcache.borrow().get(&cache_key) {
|
||||||
return Ok(ty);
|
return Ok(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = or_insert_with(self)?;
|
let ty = or_insert_with(self)?;
|
||||||
// This may overwrite the entry, but it should overwrite with the same value.
|
// This may overwrite the entry, but it should overwrite with the same value.
|
||||||
tcx.rcache.borrow_mut().insert_same(cache_key, ty);
|
tcx.ty_rcache.borrow_mut().insert_same(cache_key, ty);
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cached_predicate_for_shorthand<F>(
|
||||||
|
&mut self,
|
||||||
|
shorthand: usize,
|
||||||
|
or_insert_with: F,
|
||||||
|
) -> Result<ty::Predicate<'tcx>, Self::Error>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
|
||||||
|
{
|
||||||
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
let cache_key =
|
||||||
|
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
|
||||||
|
|
||||||
|
if let Some(&pred) = tcx.pred_rcache.borrow().get(&cache_key) {
|
||||||
|
return Ok(pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pred = or_insert_with(self)?;
|
||||||
|
// This may overwrite the entry, but it should overwrite with the same value.
|
||||||
|
tcx.pred_rcache.borrow_mut().insert_same(cache_key, pred);
|
||||||
|
Ok(pred)
|
||||||
|
}
|
||||||
|
|
||||||
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
|
@ -820,24 +843,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c, 'tcx, E> SpecializedEncoder<&'b [(ty::Predicate<'c>, Span)]>
|
impl<'a, 'b, 'tcx, E> SpecializedEncoder<ty::Predicate<'b>> for CacheEncoder<'a, 'tcx, E>
|
||||||
for CacheEncoder<'a, 'tcx, E>
|
|
||||||
where
|
where
|
||||||
E: 'a + TyEncoder,
|
E: 'a + TyEncoder,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn specialized_encode(
|
fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
|
||||||
&mut self,
|
debug_assert!(self.tcx.lift(predicate).is_some());
|
||||||
predicates: &&'b [(ty::Predicate<'c>, Span)],
|
let predicate =
|
||||||
) -> Result<(), Self::Error> {
|
unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
|
||||||
debug_assert!(self.tcx.lift(*predicates).is_some());
|
ty_codec::encode_with_shorthand(self, predicate, |encoder| {
|
||||||
let predicates = unsafe {
|
|
||||||
std::mem::transmute::<
|
|
||||||
&&'b [(ty::Predicate<'c>, Span)],
|
|
||||||
&&'tcx [(ty::Predicate<'tcx>, Span)],
|
|
||||||
>(predicates)
|
|
||||||
};
|
|
||||||
ty_codec::encode_spanned_predicates(self, predicates, |encoder| {
|
|
||||||
&mut encoder.predicate_shorthands
|
&mut encoder.predicate_shorthands
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue