Skip to content

Commit 4eef51a

Browse files
committed
Cache decoded predicate shorthands
1 parent ff4a253 commit 4eef51a

File tree

5 files changed

+118
-71
lines changed

5 files changed

+118
-71
lines changed

src/librustc_metadata/rmeta/decoder.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -294,15 +294,36 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
294294

295295
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
296296

297-
if let Some(&ty) = tcx.rcache.borrow().get(&key) {
297+
if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) {
298298
return Ok(ty);
299299
}
300300

301301
let ty = or_insert_with(self)?;
302-
tcx.rcache.borrow_mut().insert(key, ty);
302+
tcx.ty_rcache.borrow_mut().insert(key, ty);
303303
Ok(ty)
304304
}
305305

306+
fn cached_predicate_for_shorthand<F>(
307+
&mut self,
308+
shorthand: usize,
309+
or_insert_with: F,
310+
) -> Result<ty::Predicate<'tcx>, Self::Error>
311+
where
312+
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
313+
{
314+
let tcx = self.tcx();
315+
316+
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
317+
318+
if let Some(&pred) = tcx.pred_rcache.borrow().get(&key) {
319+
return Ok(pred);
320+
}
321+
322+
let pred = or_insert_with(self)?;
323+
tcx.pred_rcache.borrow_mut().insert(key, pred);
324+
Ok(pred)
325+
}
326+
306327
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
307328
where
308329
F: FnOnce(&mut Self) -> R,

src/librustc_metadata/rmeta/encoder.rs

+11-16
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,17 @@ where
239239
}
240240
}
241241

242+
impl<'b, 'tcx> SpecializedEncoder<ty::Predicate<'b>> for EncodeContext<'tcx> {
243+
fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
244+
debug_assert!(self.tcx.lift(predicate).is_some());
245+
let predicate =
246+
unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
247+
ty_codec::encode_with_shorthand(self, predicate, |encoder| {
248+
&mut encoder.predicate_shorthands
249+
})
250+
}
251+
}
252+
242253
impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
243254
fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
244255
use std::collections::hash_map::Entry;
@@ -256,22 +267,6 @@ impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
256267
}
257268
}
258269

259-
impl<'a, 'b, 'tcx> SpecializedEncoder<&'a [(ty::Predicate<'b>, Span)]> for EncodeContext<'tcx> {
260-
fn specialized_encode(
261-
&mut self,
262-
predicates: &&'a [(ty::Predicate<'b>, Span)],
263-
) -> Result<(), Self::Error> {
264-
debug_assert!(self.tcx.lift(*predicates).is_some());
265-
let predicates = unsafe {
266-
std::mem::transmute::<
267-
&&'a [(ty::Predicate<'b>, Span)],
268-
&&'tcx [(ty::Predicate<'tcx>, Span)],
269-
>(predicates)
270-
};
271-
ty_codec::encode_spanned_predicates(self, &predicates, |ecx| &mut ecx.predicate_shorthands)
272-
}
273-
}
274-
275270
impl<'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'tcx> {
276271
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
277272
f.encode_opaque(&mut self.opaque)

src/librustc_middle/ty/codec.rs

+48-34
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::arena::ArenaAllocatable;
1010
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
1111
use crate::mir::{self, interpret::Allocation};
1212
use crate::ty::subst::SubstsRef;
13-
use crate::ty::{self, List, ToPredicate, Ty, TyCtxt};
13+
use crate::ty::{self, List, Ty, TyCtxt};
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_hir::def_id::{CrateNum, DefId};
1616
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
@@ -95,23 +95,6 @@ where
9595
Ok(())
9696
}
9797

98-
pub fn encode_spanned_predicates<'tcx, E, C>(
99-
encoder: &mut E,
100-
predicates: &[(ty::Predicate<'tcx>, Span)],
101-
cache: C,
102-
) -> Result<(), E::Error>
103-
where
104-
E: TyEncoder,
105-
C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>,
106-
{
107-
predicates.len().encode(encoder)?;
108-
for (predicate, span) in predicates {
109-
encode_with_shorthand(encoder, predicate, &cache)?;
110-
span.encode(encoder)?;
111-
}
112-
Ok(())
113-
}
114-
11598
pub trait TyDecoder<'tcx>: Decoder {
11699
fn tcx(&self) -> TyCtxt<'tcx>;
117100

@@ -127,6 +110,14 @@ pub trait TyDecoder<'tcx>: Decoder {
127110
where
128111
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
129112

113+
fn cached_predicate_for_shorthand<F>(
114+
&mut self,
115+
shorthand: usize,
116+
or_insert_with: F,
117+
) -> Result<ty::Predicate<'tcx>, Self::Error>
118+
where
119+
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>;
120+
130121
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
131122
where
132123
F: FnOnce(&mut Self) -> R;
@@ -188,6 +179,26 @@ where
188179
}
189180
}
190181

182+
#[inline]
183+
pub fn decode_predicate<D>(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error>
184+
where
185+
D: TyDecoder<'tcx>,
186+
{
187+
// Handle shorthands first, if we have an usize > 0x80.
188+
if decoder.positioned_at_shorthand() {
189+
let pos = decoder.read_usize()?;
190+
assert!(pos >= SHORTHAND_OFFSET);
191+
let shorthand = pos - SHORTHAND_OFFSET;
192+
193+
decoder.cached_predicate_for_shorthand(shorthand, |decoder| {
194+
decoder.with_position(shorthand, ty::Predicate::decode)
195+
})
196+
} else {
197+
let tcx = decoder.tcx();
198+
Ok(tcx.mk_predicate(ty::PredicateKind::decode(decoder)?))
199+
}
200+
}
201+
191202
#[inline]
192203
pub fn decode_spanned_predicates<D>(
193204
decoder: &mut D,
@@ -198,20 +209,7 @@ where
198209
let tcx = decoder.tcx();
199210
Ok(tcx.arena.alloc_from_iter(
200211
(0..decoder.read_usize()?)
201-
.map(|_| {
202-
// Handle shorthands first, if we have an usize > 0x80.
203-
let predicate_kind = if decoder.positioned_at_shorthand() {
204-
let pos = decoder.read_usize()?;
205-
assert!(pos >= SHORTHAND_OFFSET);
206-
let shorthand = pos - SHORTHAND_OFFSET;
207-
208-
decoder.with_position(shorthand, ty::PredicateKind::decode)
209-
} else {
210-
ty::PredicateKind::decode(decoder)
211-
}?;
212-
let predicate = predicate_kind.to_predicate(tcx);
213-
Ok((predicate, Decodable::decode(decoder)?))
214-
})
212+
.map(|_| Decodable::decode(decoder))
215213
.collect::<Result<Vec<_>, _>>()?,
216214
))
217215
}
@@ -421,7 +419,6 @@ macro_rules! implement_ty_decoder {
421419
// FIXME(#36588): These impls are horribly unsound as they allow
422420
// the caller to pick any lifetime for `'tcx`, including `'static`.
423421

424-
rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
425422
arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
426423

427424
impl<$($typaram),*> SpecializedDecoder<CrateNum>
@@ -436,7 +433,24 @@ macro_rules! implement_ty_decoder {
436433
where &'_x ty::TyS<'_y>: UseSpecializedDecodable
437434
{
438435
fn specialized_decode(&mut self) -> Result<&'_x ty::TyS<'_y>, Self::Error> {
439-
unsafe { transmute::<Result<ty::Ty<'tcx>, Self::Error>, Result<&'_x ty::TyS<'_y>, Self::Error>>(decode_ty(self)) }
436+
unsafe {
437+
transmute::<
438+
Result<ty::Ty<'tcx>, Self::Error>,
439+
Result<&'_x ty::TyS<'_y>, Self::Error>,
440+
>(decode_ty(self))
441+
}
442+
}
443+
}
444+
445+
impl<'_x, $($typaram),*> SpecializedDecoder<ty::Predicate<'_x>>
446+
for $DecoderName<$($typaram),*> {
447+
fn specialized_decode(&mut self) -> Result<ty::Predicate<'_x>, Self::Error> {
448+
unsafe {
449+
transmute::<
450+
Result<ty::Predicate<'tcx>, Self::Error>,
451+
Result<ty::Predicate<'_x>, Self::Error>,
452+
>(decode_predicate(self))
453+
}
440454
}
441455
}
442456

src/librustc_middle/ty/context.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -939,8 +939,9 @@ pub struct GlobalCtxt<'tcx> {
939939
/// via `extern crate` item and not `--extern` option or compiler built-in.
940940
pub extern_prelude: FxHashMap<Symbol, bool>,
941941

942-
// Internal cache for metadata decoding. No need to track deps on this.
943-
pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
942+
// Internal caches for metadata decoding. No need to track deps on this.
943+
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
944+
pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
944945

945946
/// Caches the results of trait selection. This cache is used
946947
/// for things that do not have to do with the parameters in scope.
@@ -1129,7 +1130,8 @@ impl<'tcx> TyCtxt<'tcx> {
11291130
definitions,
11301131
def_path_hash_to_def_id,
11311132
queries: query::Queries::new(providers, extern_providers, on_disk_query_result_cache),
1132-
rcache: Default::default(),
1133+
ty_rcache: Default::default(),
1134+
pred_rcache: Default::default(),
11331135
selection_cache: Default::default(),
11341136
evaluation_cache: Default::default(),
11351137
crate_name: Symbol::intern(crate_name),

src/librustc_middle/ty/query/on_disk_cache.rs

+31-16
Original file line numberDiff line numberDiff line change
@@ -524,16 +524,39 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
524524
let cache_key =
525525
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
526526

527-
if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) {
527+
if let Some(&ty) = tcx.ty_rcache.borrow().get(&cache_key) {
528528
return Ok(ty);
529529
}
530530

531531
let ty = or_insert_with(self)?;
532532
// This may overwrite the entry, but it should overwrite with the same value.
533-
tcx.rcache.borrow_mut().insert_same(cache_key, ty);
533+
tcx.ty_rcache.borrow_mut().insert_same(cache_key, ty);
534534
Ok(ty)
535535
}
536536

537+
fn cached_predicate_for_shorthand<F>(
538+
&mut self,
539+
shorthand: usize,
540+
or_insert_with: F,
541+
) -> Result<ty::Predicate<'tcx>, Self::Error>
542+
where
543+
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
544+
{
545+
let tcx = self.tcx();
546+
547+
let cache_key =
548+
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
549+
550+
if let Some(&pred) = tcx.pred_rcache.borrow().get(&cache_key) {
551+
return Ok(pred);
552+
}
553+
554+
let pred = or_insert_with(self)?;
555+
// This may overwrite the entry, but it should overwrite with the same value.
556+
tcx.pred_rcache.borrow_mut().insert_same(cache_key, pred);
557+
Ok(pred)
558+
}
559+
537560
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
538561
where
539562
F: FnOnce(&mut Self) -> R,
@@ -820,24 +843,16 @@ where
820843
}
821844
}
822845

823-
impl<'a, 'b, 'c, 'tcx, E> SpecializedEncoder<&'b [(ty::Predicate<'c>, Span)]>
824-
for CacheEncoder<'a, 'tcx, E>
846+
impl<'a, 'b, 'tcx, E> SpecializedEncoder<ty::Predicate<'b>> for CacheEncoder<'a, 'tcx, E>
825847
where
826848
E: 'a + TyEncoder,
827849
{
828850
#[inline]
829-
fn specialized_encode(
830-
&mut self,
831-
predicates: &&'b [(ty::Predicate<'c>, Span)],
832-
) -> Result<(), Self::Error> {
833-
debug_assert!(self.tcx.lift(*predicates).is_some());
834-
let predicates = unsafe {
835-
std::mem::transmute::<
836-
&&'b [(ty::Predicate<'c>, Span)],
837-
&&'tcx [(ty::Predicate<'tcx>, Span)],
838-
>(predicates)
839-
};
840-
ty_codec::encode_spanned_predicates(self, predicates, |encoder| {
851+
fn specialized_encode(&mut self, predicate: &ty::Predicate<'b>) -> Result<(), Self::Error> {
852+
debug_assert!(self.tcx.lift(predicate).is_some());
853+
let predicate =
854+
unsafe { std::mem::transmute::<&ty::Predicate<'b>, &ty::Predicate<'tcx>>(predicate) };
855+
ty_codec::encode_with_shorthand(self, predicate, |encoder| {
841856
&mut encoder.predicate_shorthands
842857
})
843858
}

0 commit comments

Comments
 (0)