about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-11-14 14:50:03 +0100
committerMichael Woerister <michaelwoerister@posteo>2017-11-14 14:50:03 +0100
commit2087d5ebfa06a32b4142f3cebbe4add0e62a9588 (patch)
tree9a27755f9c38f7b017527ea8643ccb9e5d107745
parentde0317e267812563e87cd0a03f9e5d486c0bdae8 (diff)
downloadrust-2087d5ebfa06a32b4142f3cebbe4add0e62a9588.tar.gz
rust-2087d5ebfa06a32b4142f3cebbe4add0e62a9588.zip
incr.comp.: Do some verification on data decoded from incr. comp. cache.
-rw-r--r--src/librustc/ty/maps/on_disk_cache.rs68
1 files changed, 62 insertions, 6 deletions
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 7431d6dd497..121b81111f2 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -34,6 +34,11 @@ use ty::codec::{self as ty_codec, TyDecoder};
 use ty::context::TyCtxt;
 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
 /// previous compilation session. This data will eventually include the results
 /// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -91,15 +96,17 @@ impl<'sess> OnDiskCache<'sess> {
 
             // Decode Diagnostics
             let prev_diagnostics: FxHashMap<_, _> = {
-                let diagnostics = EncodedPrevDiagnostics::decode(&mut decoder)
-                    .expect("Error while trying to decode prev. diagnostics \
-                             from incr. comp. cache.");
+                let diagnostics: EncodedPrevDiagnostics =
+                    decode_tagged(&mut decoder, PREV_DIAGNOSTICS_TAG)
+                        .expect("Error while trying to decode previous session \
+                                 diagnostics from incr. comp. cache.");
+
                 diagnostics.into_iter().collect()
             };
 
             // Decode DefPathTables
             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");
 
             (prev_diagnostics, prev_def_path_tables)
@@ -176,7 +183,7 @@ impl<'sess> OnDiskCache<'sess> {
                 .map(|(k, v)| (SerializedDepNodeIndex::new(k.index()), v.clone()))
                 .collect();
 
-        diagnostics.encode(&mut encoder)?;
+        encoder.encode_tagged(PREV_DIAGNOSTICS_TAG, &diagnostics)?;
 
 
         // Encode all DefPathTables
@@ -192,7 +199,7 @@ impl<'sess> OnDiskCache<'sess> {
             }
         }).collect();
 
-        def_path_tables.encode(&mut encoder)?;
+        encoder.encode_tagged(DEF_PATH_TABLE_TAG, &def_path_tables)?;
 
         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> {
 
     #[inline]
@@ -565,6 +596,30 @@ struct CacheEncoder<'enc, 'tcx, E>
     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>
     where E: 'enc + ty_codec::TyEncoder
 {
@@ -644,3 +699,4 @@ impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
         emit_str(&str);
     }
 }
+