From 87691846e3c92fa2cccd66f7ce3d7b00ee0de1d4 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 24 Oct 2017 14:51:26 +0200 Subject: [PATCH] incr.comp.: Add documentation for OnDiskCache. --- src/librustc/ty/maps/on_disk_cache.rs | 83 ++++++++++++++++++--------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index b1b84438813..26581501234 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -22,35 +22,42 @@ use std::mem; use syntax::codemap::{CodeMap, StableFilemapId}; use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP}; +/// `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 +/// any diagnostics that have been emitted during a query. pub struct OnDiskCache<'sess> { + // The diagnostics emitted during the previous compilation session. prev_diagnostics: FxHashMap>, + // This field collects all Diagnostics emitted during the current + // compilation session. + current_diagnostics: RefCell>>, + + // This will eventually be needed for creating Decoders that can rebase + // spans. _prev_filemap_starts: BTreeMap, codemap: &'sess CodeMap, - - current_diagnostics: RefCell>>, } +// This type is used only for (de-)serialization. #[derive(RustcEncodable, RustcDecodable)] struct Header { prev_filemap_starts: BTreeMap, } +// This type is used only for (de-)serialization. #[derive(RustcEncodable, RustcDecodable)] struct Body { diagnostics: Vec<(SerializedDepNodeIndex, Vec)>, } impl<'sess> OnDiskCache<'sess> { - pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> { - OnDiskCache { - prev_diagnostics: FxHashMap(), - _prev_filemap_starts: BTreeMap::new(), - codemap, - current_diagnostics: RefCell::new(FxHashMap()), - } - } - + /// Create a new OnDiskCache instance from the serialized data in `data`. + /// Note that the current implementation (which only deals with diagnostics + /// so far) will eagerly deserialize the complete cache. Once we are + /// dealing with larger amounts of data (i.e. cached query results), + /// deserialization will need to happen lazily. pub fn new(sess: &'sess Session, data: &[u8]) -> OnDiskCache<'sess> { debug_assert!(sess.opts.incremental.is_some()); @@ -75,6 +82,15 @@ impl<'sess> OnDiskCache<'sess> { } } + pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> { + OnDiskCache { + prev_diagnostics: FxHashMap(), + _prev_filemap_starts: BTreeMap::new(), + codemap, + current_diagnostics: RefCell::new(FxHashMap()), + } + } + pub fn serialize<'a, 'tcx, E>(&self, encoder: &mut E) -> Result<(), E::Error> @@ -101,12 +117,16 @@ impl<'sess> OnDiskCache<'sess> { Ok(()) } + /// Load a diagnostic emitted during the previous compilation session. pub fn load_diagnostics(&self, dep_node_index: SerializedDepNodeIndex) -> Vec { self.prev_diagnostics.get(&dep_node_index).cloned().unwrap_or(vec![]) } + /// Store a diagnostic emitted during the current compilation session. + /// Anything stored like this will be available via `load_diagnostics` in + /// the next compilation session. pub fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: Vec) { @@ -115,6 +135,10 @@ impl<'sess> OnDiskCache<'sess> { debug_assert!(prev.is_none()); } + /// Store a diagnostic emitted during computation of an anonymous query. + /// Since many anonymous queries can share the same `DepNode`, we aggregate + /// them -- as opposed to regular queries where we assume that there is a + /// 1:1 relationship between query-key and `DepNode`. pub fn store_diagnostics_for_anon_node(&self, dep_node_index: DepNodeIndex, mut diagnostics: Vec) { @@ -128,23 +152,9 @@ impl<'sess> OnDiskCache<'sess> { } } -impl<'a> SpecializedDecoder for CacheDecoder<'a> { - fn specialized_decode(&mut self) -> Result { - let lo = BytePos::decode(self)?; - let hi = BytePos::decode(self)?; - - if let Some((prev_filemap_start, filemap_id)) = self.find_filemap_prev_bytepos(lo) { - if let Some(current_filemap) = self.codemap.filemap_by_stable_id(filemap_id) { - let lo = (lo + current_filemap.start_pos) - prev_filemap_start; - let hi = (hi + current_filemap.start_pos) - prev_filemap_start; - return Ok(Span::new(lo, hi, NO_EXPANSION)); - } - } - - Ok(DUMMY_SP) - } -} - +/// A decoder that can read the incr. comp. cache. It is similar to the one +/// we use for crate metadata decoding in that it can rebase spans and +/// eventually will also handle things that contain `Ty` instances. struct CacheDecoder<'a> { opaque: opaque::Decoder<'a>, codemap: &'a CodeMap, @@ -202,3 +212,20 @@ impl<'sess> Decoder for CacheDecoder<'sess> { self.opaque.error(err) } } + +impl<'a> SpecializedDecoder for CacheDecoder<'a> { + fn specialized_decode(&mut self) -> Result { + let lo = BytePos::decode(self)?; + let hi = BytePos::decode(self)?; + + if let Some((prev_filemap_start, filemap_id)) = self.find_filemap_prev_bytepos(lo) { + if let Some(current_filemap) = self.codemap.filemap_by_stable_id(filemap_id) { + let lo = (lo + current_filemap.start_pos) - prev_filemap_start; + let hi = (hi + current_filemap.start_pos) - prev_filemap_start; + return Ok(Span::new(lo, hi, NO_EXPANSION)); + } + } + + Ok(DUMMY_SP) + } +}