incr.comp.: Add documentation for OnDiskCache.
This commit is contained in:
parent
f55425dfcd
commit
87691846e3
1 changed files with 55 additions and 28 deletions
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue