From 8cbd6fe33155fde25146d2cf03aa26e450086106 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 31 Aug 2016 16:51:24 -0400 Subject: [PATCH] ICH: Share codemap cache between subsequent runs of the ICH visitor. --- .../calculate_svh/caching_codemap_view.rs | 97 +++++++++++++++++++ src/librustc_incremental/calculate_svh/mod.rs | 8 +- .../calculate_svh/svh_visitor.rs | 92 ++---------------- 3 files changed, 111 insertions(+), 86 deletions(-) create mode 100644 src/librustc_incremental/calculate_svh/caching_codemap_view.rs diff --git a/src/librustc_incremental/calculate_svh/caching_codemap_view.rs b/src/librustc_incremental/calculate_svh/caching_codemap_view.rs new file mode 100644 index 000000000000..32aa5a427287 --- /dev/null +++ b/src/librustc_incremental/calculate_svh/caching_codemap_view.rs @@ -0,0 +1,97 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::ty::TyCtxt; +use std::rc::Rc; +use syntax::codemap::CodeMap; +use syntax_pos::{BytePos, FileMap}; + +#[derive(Clone)] +struct CacheEntry { + time_stamp: usize, + line_number: usize, + line_start: BytePos, + line_end: BytePos, + file: Rc, +} + +pub struct CachingCodemapView<'tcx> { + codemap: &'tcx CodeMap, + line_cache: [CacheEntry; 3], + time_stamp: usize, +} + +impl<'tcx> CachingCodemapView<'tcx> { + pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> { + let codemap = tcx.sess.codemap(); + let first_file = codemap.files.borrow()[0].clone(); + let entry = CacheEntry { + time_stamp: 0, + line_number: 0, + line_start: BytePos(0), + line_end: BytePos(0), + file: first_file, + }; + + CachingCodemapView { + codemap: codemap, + line_cache: [entry.clone(), entry.clone(), entry.clone()], + time_stamp: 0, + } + } + + pub fn codemap(&self) -> &'tcx CodeMap { + self.codemap + } + + pub fn byte_pos_to_line_and_col(&mut self, + pos: BytePos) + -> (Rc, usize, BytePos) { + self.time_stamp += 1; + + // Check if the position is in one of the cached lines + for cache_entry in self.line_cache.iter_mut() { + if pos >= cache_entry.line_start && pos < cache_entry.line_end { + cache_entry.time_stamp = self.time_stamp; + return (cache_entry.file.clone(), + cache_entry.line_number, + pos - cache_entry.line_start); + } + } + + // No cache hit ... + let mut oldest = 0; + for index in 1 .. self.line_cache.len() { + if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp { + oldest = index; + } + } + + let cache_entry = &mut self.line_cache[oldest]; + + // If the entry doesn't point to the correct file, fix it up + if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos { + let file_index = self.codemap.lookup_filemap_idx(pos); + cache_entry.file = self.codemap.files.borrow()[file_index].clone(); + } + + let line_index = cache_entry.file.lookup_line(pos).unwrap(); + let line_bounds = cache_entry.file.line_bounds(line_index); + + cache_entry.line_number = line_index + 1; + cache_entry.line_start = line_bounds.0; + cache_entry.line_end = line_bounds.1; + cache_entry.time_stamp = self.time_stamp; + + return (cache_entry.file.clone(), + cache_entry.line_number, + pos - cache_entry.line_start); + } +} diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 6ad93d8f4733..c54fe2114517 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -40,9 +40,11 @@ use rustc::session::config::DebugInfoLevel::NoDebugInfo; use self::def_path_hash::DefPathHashes; use self::svh_visitor::StrictVersionHashVisitor; +use self::caching_codemap_view::CachingCodemapView; mod def_path_hash; mod svh_visitor; +mod caching_codemap_view; pub type IncrementalHashesMap = FnvHashMap, u64>; @@ -55,7 +57,8 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) tcx: tcx, hashes: FnvHashMap(), def_path_hashes: DefPathHashes::new(tcx), - hash_spans: hash_spans + codemap: CachingCodemapView::new(tcx), + hash_spans: hash_spans, }; record_time(&tcx.sess.perf_stats.incr_comp_hashes_time, || { visitor.calculate_def_id(DefId::local(CRATE_DEF_INDEX), @@ -69,6 +72,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) struct HashItemsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path_hashes: DefPathHashes<'a, 'tcx>, + codemap: CachingCodemapView<'tcx>, hashes: IncrementalHashesMap, hash_spans: bool, } @@ -92,6 +96,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { walk_op(&mut StrictVersionHashVisitor::new(&mut state, self.tcx, &mut self.def_path_hashes, + &mut self.codemap, self.hash_spans)); let item_hash = state.finish(); self.hashes.insert(DepNode::Hir(def_id), item_hash); @@ -132,6 +137,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { let mut visitor = StrictVersionHashVisitor::new(&mut crate_state, self.tcx, &mut self.def_path_hashes, + &mut self.codemap, self.hash_spans); visitor.hash_attributes(&krate.attrs); } diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index e871dd5bcbff..417f09c1c9d5 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -17,18 +17,17 @@ use self::SawExprComponent::*; use self::SawAbiComponent::*; use syntax::ast::{self, Name, NodeId, Attribute}; use syntax::parse::token; -use syntax::codemap::CodeMap; -use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos, FileMap}; +use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos}; use rustc::hir; use rustc::hir::*; use rustc::hir::def::{Def, PathResolution}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit as visit; use rustc::ty::TyCtxt; -use std::rc::Rc; use std::hash::{Hash, SipHasher}; use super::def_path_hash::DefPathHashes; +use super::caching_codemap_view::CachingCodemapView; const IGNORED_ATTRIBUTES: &'static [&'static str] = &["cfg", "rustc_clean", @@ -40,92 +39,14 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> { // collect a deterministic hash of def-ids that we have seen def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>, hash_spans: bool, - codemap: CachingCodemapView<'tcx>, -} - -#[derive(Clone)] -struct CacheEntry { - time_stamp: usize, - line_number: usize, - line_start: BytePos, - line_end: BytePos, - file: Rc, -} - -struct CachingCodemapView<'tcx> { - codemap: &'tcx CodeMap, - line_cache: [CacheEntry; 3], - time_stamp: usize, -} - -impl<'tcx> CachingCodemapView<'tcx> { - fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> { - let codemap = tcx.sess.codemap(); - let first_file = codemap.files.borrow()[0].clone(); - let entry = CacheEntry { - time_stamp: 0, - line_number: 0, - line_start: BytePos(0), - line_end: BytePos(0), - file: first_file, - }; - - CachingCodemapView { - codemap: codemap, - line_cache: [entry.clone(), entry.clone(), entry.clone()], - time_stamp: 0, - } - } - - fn byte_pos_to_line_and_col(&mut self, - pos: BytePos) - -> (Rc, usize, BytePos) { - self.time_stamp += 1; - - // Check if the position is in one of the cached lines - for cache_entry in self.line_cache.iter_mut() { - if pos >= cache_entry.line_start && pos < cache_entry.line_end { - cache_entry.time_stamp = self.time_stamp; - return (cache_entry.file.clone(), - cache_entry.line_number, - pos - cache_entry.line_start); - } - } - - // No cache hit ... - let mut oldest = 0; - for index in 1 .. self.line_cache.len() { - if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp { - oldest = index; - } - } - - let cache_entry = &mut self.line_cache[oldest]; - - // If the entry doesn't point to the correct file, fix it up - if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos { - let file_index = self.codemap.lookup_filemap_idx(pos); - cache_entry.file = self.codemap.files.borrow()[file_index].clone(); - } - - let line_index = cache_entry.file.lookup_line(pos).unwrap(); - let line_bounds = cache_entry.file.line_bounds(line_index); - - cache_entry.line_number = line_index + 1; - cache_entry.line_start = line_bounds.0; - cache_entry.line_end = line_bounds.1; - cache_entry.time_stamp = self.time_stamp; - - return (cache_entry.file.clone(), - cache_entry.line_number, - pos - cache_entry.line_start); - } + codemap: &'a mut CachingCodemapView<'tcx>, } impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { pub fn new(st: &'a mut SipHasher, tcx: TyCtxt<'hash, 'tcx, 'tcx>, def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>, + codemap: &'a mut CachingCodemapView<'tcx>, hash_spans: bool) -> Self { StrictVersionHashVisitor { @@ -133,7 +54,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { tcx: tcx, def_path_hashes: def_path_hashes, hash_spans: hash_spans, - codemap: CachingCodemapView::new(tcx), + codemap: codemap, } } @@ -178,7 +99,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { expansion_kind).hash(self.st); if expansion_kind == SawSpanExpnKind::SomeExpansion { - self.hash_span(self.codemap.codemap.source_callsite(span)); + let call_site = self.codemap.codemap().source_callsite(span); + self.hash_span(call_site); } }