incr.comp.: Do some verification on data decoded from incr. comp. cache.
This commit is contained in:
parent
de0317e267
commit
2087d5ebfa
@ -34,6 +34,11 @@ use ty::codec::{self as ty_codec, TyDecoder};
|
|||||||
use ty::context::TyCtxt;
|
use ty::context::TyCtxt;
|
||||||
use ty::subst::Substs;
|
use ty::subst::Substs;
|
||||||
|
|
||||||
|
// Some magic values used for verifying that encoding and decoding. These are
|
||||||
|
// basically random numbers.
|
||||||
|
const PREV_DIAGNOSTICS_TAG: u64 = 0x1234_5678_A1A1_A1A1;
|
||||||
|
const DEF_PATH_TABLE_TAG: u64 = 0x1234_5678_B2B2_B2B2;
|
||||||
|
|
||||||
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
|
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
|
||||||
/// previous compilation session. This data will eventually include the results
|
/// previous compilation session. This data will eventually include the results
|
||||||
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
|
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
|
||||||
@ -91,15 +96,17 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
|
|
||||||
// Decode Diagnostics
|
// Decode Diagnostics
|
||||||
let prev_diagnostics: FxHashMap<_, _> = {
|
let prev_diagnostics: FxHashMap<_, _> = {
|
||||||
let diagnostics = EncodedPrevDiagnostics::decode(&mut decoder)
|
let diagnostics: EncodedPrevDiagnostics =
|
||||||
.expect("Error while trying to decode prev. diagnostics \
|
decode_tagged(&mut decoder, PREV_DIAGNOSTICS_TAG)
|
||||||
from incr. comp. cache.");
|
.expect("Error while trying to decode previous session \
|
||||||
|
diagnostics from incr. comp. cache.");
|
||||||
|
|
||||||
diagnostics.into_iter().collect()
|
diagnostics.into_iter().collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Decode DefPathTables
|
// Decode DefPathTables
|
||||||
let prev_def_path_tables: Vec<DefPathTable> =
|
let prev_def_path_tables: Vec<DefPathTable> =
|
||||||
Decodable::decode(&mut decoder)
|
decode_tagged(&mut decoder, DEF_PATH_TABLE_TAG)
|
||||||
.expect("Error while trying to decode cached DefPathTables");
|
.expect("Error while trying to decode cached DefPathTables");
|
||||||
|
|
||||||
(prev_diagnostics, prev_def_path_tables)
|
(prev_diagnostics, prev_def_path_tables)
|
||||||
@ -176,7 +183,7 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
.map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
|
.map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
diagnostics.encode(&mut encoder)?;
|
encoder.encode_tagged(PREV_DIAGNOSTICS_TAG, &diagnostics)?;
|
||||||
|
|
||||||
|
|
||||||
// Encode all DefPathTables
|
// Encode all DefPathTables
|
||||||
@ -192,7 +199,7 @@ impl<'sess> OnDiskCache<'sess> {
|
|||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
def_path_tables.encode(&mut encoder)?;
|
encoder.encode_tagged(DEF_PATH_TABLE_TAG, &def_path_tables)?;
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
||||||
@ -342,6 +349,30 @@ impl<'a, 'tcx, 'x> Decoder for CacheDecoder<'a, 'tcx, 'x> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode something that was encoded with encode_tagged() and verify that the
|
||||||
|
// tag matches and the correct amount of bytes was read.
|
||||||
|
fn decode_tagged<'a, 'tcx, D, T, V>(decoder: &mut D,
|
||||||
|
expected_tag: T)
|
||||||
|
-> Result<V, D::Error>
|
||||||
|
where T: Decodable + Eq + ::std::fmt::Debug,
|
||||||
|
V: Decodable,
|
||||||
|
D: Decoder + ty_codec::TyDecoder<'a, 'tcx>,
|
||||||
|
'tcx: 'a,
|
||||||
|
{
|
||||||
|
let start_pos = decoder.position();
|
||||||
|
|
||||||
|
let actual_tag = T::decode(decoder)?;
|
||||||
|
assert_eq!(actual_tag, expected_tag);
|
||||||
|
let value = V::decode(decoder)?;
|
||||||
|
let end_pos = decoder.position();
|
||||||
|
|
||||||
|
let expected_len: u64 = Decodable::decode(decoder)?;
|
||||||
|
assert_eq!((end_pos - start_pos) as u64, expected_len);
|
||||||
|
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
|
impl<'a, 'tcx: 'a, 'x> ty_codec::TyDecoder<'a, 'tcx> for CacheDecoder<'a, 'tcx, 'x> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -565,6 +596,30 @@ struct CacheEncoder<'enc, 'tcx, E>
|
|||||||
definitions: &'enc Definitions,
|
definitions: &'enc Definitions,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'enc, 'tcx, E> CacheEncoder<'enc, 'tcx, E>
|
||||||
|
where E: 'enc + ty_codec::TyEncoder
|
||||||
|
{
|
||||||
|
/// Encode something with additional information that allows to do some
|
||||||
|
/// sanity checks when decoding the data again. This method will first
|
||||||
|
/// encode the specified tag, then the given value, then the number of
|
||||||
|
/// bytes taken up by tag and value. On decoding, we can then verify that
|
||||||
|
/// we get the expected tag and read the expected number of bytes.
|
||||||
|
fn encode_tagged<T: Encodable, V: Encodable>(&mut self,
|
||||||
|
tag: T,
|
||||||
|
value: &V)
|
||||||
|
-> Result<(), E::Error>
|
||||||
|
{
|
||||||
|
use ty::codec::TyEncoder;
|
||||||
|
let start_pos = self.position();
|
||||||
|
|
||||||
|
tag.encode(self)?;
|
||||||
|
value.encode(self)?;
|
||||||
|
|
||||||
|
let end_pos = self.position();
|
||||||
|
((end_pos - start_pos) as u64).encode(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
|
impl<'enc, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'enc, 'tcx, E>
|
||||||
where E: 'enc + ty_codec::TyEncoder
|
where E: 'enc + ty_codec::TyEncoder
|
||||||
{
|
{
|
||||||
@ -644,3 +699,4 @@ impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
|
|||||||
emit_str(&str);
|
emit_str(&str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user