1
Fork 0

incr.comp.: Add documentation for OnDiskCache.

This commit is contained in:
Michael Woerister 2017-10-24 14:51:26 +02:00
parent f55425dfcd
commit 87691846e3

View file

@ -22,35 +22,42 @@ use std::mem;
use syntax::codemap::{CodeMap, StableFilemapId}; use syntax::codemap::{CodeMap, StableFilemapId};
use syntax_pos::{BytePos, Span, NO_EXPANSION, DUMMY_SP}; 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> { pub struct OnDiskCache<'sess> {
// The diagnostics emitted during the previous compilation session.
prev_diagnostics: FxHashMap<SerializedDepNodeIndex, Vec<Diagnostic>>, prev_diagnostics: FxHashMap<SerializedDepNodeIndex, Vec<Diagnostic>>,
// This field collects all Diagnostics emitted during the current
// compilation session.
current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
// This will eventually be needed for creating Decoders that can rebase
// spans.
_prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>, _prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
codemap: &'sess CodeMap, codemap: &'sess CodeMap,
current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
} }
// This type is used only for (de-)serialization.
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
struct Header { struct Header {
prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>, prev_filemap_starts: BTreeMap<BytePos, StableFilemapId>,
} }
// This type is used only for (de-)serialization.
#[derive(RustcEncodable, RustcDecodable)] #[derive(RustcEncodable, RustcDecodable)]
struct Body { struct Body {
diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)>, diagnostics: Vec<(SerializedDepNodeIndex, Vec<Diagnostic>)>,
} }
impl<'sess> OnDiskCache<'sess> { impl<'sess> OnDiskCache<'sess> {
pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> { /// Create a new OnDiskCache instance from the serialized data in `data`.
OnDiskCache { /// Note that the current implementation (which only deals with diagnostics
prev_diagnostics: FxHashMap(), /// so far) will eagerly deserialize the complete cache. Once we are
_prev_filemap_starts: BTreeMap::new(), /// dealing with larger amounts of data (i.e. cached query results),
codemap, /// deserialization will need to happen lazily.
current_diagnostics: RefCell::new(FxHashMap()),
}
}
pub fn new(sess: &'sess Session, data: &[u8]) -> OnDiskCache<'sess> { pub fn new(sess: &'sess Session, data: &[u8]) -> OnDiskCache<'sess> {
debug_assert!(sess.opts.incremental.is_some()); 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, pub fn serialize<'a, 'tcx, E>(&self,
encoder: &mut E) encoder: &mut E)
-> Result<(), E::Error> -> Result<(), E::Error>
@ -101,12 +117,16 @@ impl<'sess> OnDiskCache<'sess> {
Ok(()) Ok(())
} }
/// Load a diagnostic emitted during the previous compilation session.
pub fn load_diagnostics(&self, pub fn load_diagnostics(&self,
dep_node_index: SerializedDepNodeIndex) dep_node_index: SerializedDepNodeIndex)
-> Vec<Diagnostic> { -> Vec<Diagnostic> {
self.prev_diagnostics.get(&dep_node_index).cloned().unwrap_or(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, pub fn store_diagnostics(&self,
dep_node_index: DepNodeIndex, dep_node_index: DepNodeIndex,
diagnostics: Vec<Diagnostic>) { diagnostics: Vec<Diagnostic>) {
@ -115,6 +135,10 @@ impl<'sess> OnDiskCache<'sess> {
debug_assert!(prev.is_none()); 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, pub fn store_diagnostics_for_anon_node(&self,
dep_node_index: DepNodeIndex, dep_node_index: DepNodeIndex,
mut diagnostics: Vec<Diagnostic>) { mut diagnostics: Vec<Diagnostic>) {
@ -128,23 +152,9 @@ impl<'sess> OnDiskCache<'sess> {
} }
} }
impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> { /// A decoder that can read the incr. comp. cache. It is similar to the one
fn specialized_decode(&mut self) -> Result<Span, Self::Error> { /// we use for crate metadata decoding in that it can rebase spans and
let lo = BytePos::decode(self)?; /// eventually will also handle things that contain `Ty` instances.
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)
}
}
struct CacheDecoder<'a> { struct CacheDecoder<'a> {
opaque: opaque::Decoder<'a>, opaque: opaque::Decoder<'a>,
codemap: &'a CodeMap, codemap: &'a CodeMap,
@ -202,3 +212,20 @@ impl<'sess> Decoder for CacheDecoder<'sess> {
self.opaque.error(err) self.opaque.error(err)
} }
} }
impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
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)
}
}