提交 21dd71f5 编写于 作者: M Michael Woerister

incr.comp.: Track expanded spans instead of FileMaps.

上级 5b13bff5
......@@ -176,7 +176,6 @@ pub enum DepNode<D: Clone + Debug> {
IsMirAvailable(D),
ItemAttrs(D),
FnArgNames(D),
FileMap(D, Arc<String>),
}
impl<D: Clone + Debug> DepNode<D> {
......@@ -307,7 +306,6 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())),
}
}
}
......
......@@ -8,11 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use dep_graph::{DepGraph, DepNode};
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
use rustc_data_structures::bitvec::BitVector;
use std::rc::Rc;
use std::sync::Arc;
use syntax::codemap::CodeMap;
use syntax_pos::{BytePos, FileMap};
use ty::TyCtxt;
......@@ -31,14 +27,12 @@ pub struct CachingCodemapView<'tcx> {
codemap: &'tcx CodeMap,
line_cache: [CacheEntry; 3],
time_stamp: usize,
dep_graph: DepGraph,
dep_tracking_reads: BitVector,
}
impl<'tcx> CachingCodemapView<'tcx> {
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
let codemap = tcx.sess.codemap();
let files = codemap.files_untracked();
let files = codemap.files();
let first_file = files[0].clone();
let entry = CacheEntry {
time_stamp: 0,
......@@ -50,11 +44,9 @@ pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
};
CachingCodemapView {
dep_graph: tcx.dep_graph.clone(),
codemap: codemap,
line_cache: [entry.clone(), entry.clone(), entry.clone()],
time_stamp: 0,
dep_tracking_reads: BitVector::new(files.len()),
}
}
......@@ -67,9 +59,6 @@ pub fn byte_pos_to_line_and_col(&mut self,
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;
if self.dep_tracking_reads.insert(cache_entry.file_index) {
self.dep_graph.read(dep_node(cache_entry));
}
return Some((cache_entry.file.clone(),
cache_entry.line_number,
......@@ -90,7 +79,7 @@ pub fn byte_pos_to_line_and_col(&mut self,
// 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_valid;
let files = self.codemap.files_untracked();
let files = self.codemap.files();
if files.len() > 0 {
let file_index = self.codemap.lookup_filemap_idx(pos);
......@@ -120,21 +109,8 @@ pub fn byte_pos_to_line_and_col(&mut self,
cache_entry.line_end = line_bounds.1;
cache_entry.time_stamp = self.time_stamp;
if self.dep_tracking_reads.insert(cache_entry.file_index) {
self.dep_graph.read(dep_node(cache_entry));
}
return Some((cache_entry.file.clone(),
cache_entry.line_number,
pos - cache_entry.line_start));
}
}
fn dep_node(cache_entry: &CacheEntry) -> DepNode<DefId> {
let def_id = DefId {
krate: CrateNum::from_u32(cache_entry.file.crate_of_origin),
index: CRATE_DEF_INDEX,
};
let name = Arc::new(cache_entry.file.name.clone());
DepNode::FileMap(def_id, name)
}
......@@ -74,6 +74,11 @@ pub fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Self {
}
}
pub fn force_span_hashing(mut self) -> Self {
self.hash_spans = true;
self
}
#[inline]
pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self,
hash_bodies: bool,
......
......@@ -22,11 +22,55 @@
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info,
is_user_variable});
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
mutability,
ty,
name,
source_info,
is_user_variable
});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Terminator<'tcx> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
let mir::Terminator {
ref kind,
ref source_info,
} = *self;
let hash_spans_unconditionally = match *kind {
mir::TerminatorKind::Assert { .. } => {
// Assert terminators generate a panic message that contains the
// source location, so we always have to feed its span into the
// ICH.
true
}
mir::TerminatorKind::Goto { .. } |
mir::TerminatorKind::SwitchInt { .. } |
mir::TerminatorKind::Resume |
mir::TerminatorKind::Return |
mir::TerminatorKind::Unreachable |
mir::TerminatorKind::Drop { .. } |
mir::TerminatorKind::DropAndReplace { .. } |
mir::TerminatorKind::Call { .. } => false,
};
if hash_spans_unconditionally {
hcx.while_hashing_spans(true, |hcx| {
source_info.hash_stable(hcx, hasher);
})
} else {
source_info.hash_stable(hcx, hasher);
}
kind.hash_stable(hcx, hasher);
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
#[inline]
......
......@@ -11,8 +11,9 @@
pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo};
pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};
use dep_graph::{DepGraph, DepNode};
use hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX};
use dep_graph::DepGraph;
use hir::def_id::{CrateNum, DefIndex};
use lint;
use middle::cstore::CrateStore;
use middle::dependency_format;
......@@ -32,7 +33,7 @@
use syntax::symbol::Symbol;
use syntax::{ast, codemap};
use syntax::feature_gate::AttributeType;
use syntax_pos::{Span, MultiSpan, FileMap};
use syntax_pos::{Span, MultiSpan};
use rustc_back::{LinkerFlavor, PanicStrategy};
use rustc_back::target::Target;
......@@ -46,7 +47,6 @@
use std::rc::Rc;
use std::fmt;
use std::time::Duration;
use std::sync::Arc;
mod code_stats;
pub mod config;
......@@ -626,21 +626,6 @@ pub fn build_session_(sopts: config::Options,
};
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
// Hook up the codemap with a callback that allows it to register FileMap
// accesses with the dependency graph.
let cm_depgraph = dep_graph.clone();
let codemap_dep_tracking_callback = Box::new(move |filemap: &FileMap| {
let def_id = DefId {
krate: CrateNum::from_u32(filemap.crate_of_origin),
index: CRATE_DEF_INDEX,
};
let name = Arc::new(filemap.name.clone());
let dep_node = DepNode::FileMap(def_id, name);
cm_depgraph.read(dep_node);
});
codemap.set_dep_tracking_callback(codemap_dep_tracking_callback);
let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap);
let default_sysroot = match sopts.maybe_sysroot {
Some(_) => None,
......
......@@ -29,10 +29,9 @@
use std::cell::RefCell;
use std::hash::Hash;
use std::sync::Arc;
use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId};
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ich::{Fingerprint, StableHashingContext};
use rustc::ty::TyCtxt;
......@@ -155,11 +154,6 @@ fn compute_crate_hash(&mut self) {
// We want to incoporate these into the
// SVH.
}
DepNode::FileMap(..) => {
// These don't make a semantic
// difference, filter them out.
return None
}
DepNode::AllLocalTraitImpls => {
// These are already covered by hashing
// the HIR.
......@@ -306,24 +300,6 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
}
for filemap in tcx.sess
.codemap()
.files_untracked()
.iter()
.filter(|fm| !fm.is_imported()) {
assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin);
let def_id = DefId {
krate: LOCAL_CRATE,
index: CRATE_DEF_INDEX,
};
let name = Arc::new(filemap.name.clone());
let dep_node = DepNode::FileMap(def_id, name);
let mut hasher = IchHasher::new();
filemap.hash_stable(&mut visitor.hcx, &mut hasher);
let fingerprint = hasher.finish();
visitor.hashes.insert(dep_node, fingerprint);
}
visitor.compute_and_store_ich_for_trait_impls(krate);
});
......
......@@ -51,8 +51,7 @@ pub fn is_hashable(dep_node: &DepNode<DefId>) -> bool {
match *dep_node {
DepNode::Krate |
DepNode::Hir(_) |
DepNode::HirBody(_) |
DepNode::FileMap(..) =>
DepNode::HirBody(_) =>
true,
DepNode::MetaData(def_id) |
DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(),
......@@ -77,20 +76,6 @@ pub fn hash(&mut self, dep_node: &DepNode<DefId>) -> Option<Fingerprint> {
Some(self.incremental_hashes_map[dep_node])
}
DepNode::FileMap(def_id, ref name) => {
if def_id.is_local() {
// We will have been able to retrace the DefId (which is
// always the local CRATE_DEF_INDEX), but the file with the
// given name might have been removed, so we use get() in
// order to allow for that case.
self.incremental_hashes_map.get(dep_node).map(|x| *x)
} else {
Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()),
def_id.krate,
|this| &mut this.global_metadata_hashes))
}
}
// MetaData from other crates is an *input* to us.
// MetaData nodes from *our* crates are an *output*; we
// don't hash them, but we do compute a hash for them and
......@@ -242,7 +227,6 @@ fn load_from_data(&mut self,
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
let dep_node = match dep_node {
DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind),
DepNode::FileMap(_, name) => DepNode::FileMap(def_id, name),
other => {
bug!("unexpected DepNode variant: {:?}", other)
}
......
......@@ -18,7 +18,7 @@
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::DefPathTable;
use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
use rustc::ich::{StableHashingContext, Fingerprint};
use rustc::ich::Fingerprint;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::lang_items;
use rustc::mir;
......@@ -29,7 +29,6 @@
use rustc::util::nodemap::{FxHashMap, NodeSet};
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use std::hash::Hash;
use std::intrinsics;
......@@ -37,7 +36,6 @@
use std::io::Cursor;
use std::path::Path;
use std::rc::Rc;
use std::sync::Arc;
use std::u32;
use syntax::ast::{self, CRATE_NODE_ID};
use syntax::codemap::Spanned;
......@@ -284,7 +282,6 @@ fn encode_codemap(&mut self) -> LazySeq<syntax_pos::FileMap> {
let codemap = self.tcx.sess.codemap();
let all_filemaps = codemap.files();
let hcx = &mut StableHashingContext::new(self.tcx);
let (working_dir, working_dir_was_remapped) = self.tcx.sess.working_dir.clone();
let adapted = all_filemaps.iter()
......@@ -316,21 +313,10 @@ fn encode_codemap(&mut self) -> LazySeq<syntax_pos::FileMap> {
adapted.name = abs_path;
Rc::new(adapted)
}
});
let filemaps: Vec<_> = if self.compute_ich {
adapted.inspect(|filemap| {
let mut hasher = StableHasher::new();
filemap.hash_stable(hcx, &mut hasher);
let fingerprint = hasher.finish();
let dep_node = DepNode::FileMap((), Arc::new(filemap.name.clone()));
self.metadata_hashes.global_hashes.push((dep_node, fingerprint));
}).collect()
} else {
adapted.collect()
};
})
.collect::<Vec<_>>();
self.lazy_seq_ref(filemaps.iter().map(|fm| &**fm))
self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
}
fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
......
......@@ -35,7 +35,17 @@ pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
tcx: tcx,
ecx: ecx,
hcx: if compute_ich {
Some((StableHashingContext::new(tcx), StableHasher::new()))
// We are always hashing spans for things in metadata because
// don't know if a downstream crate will use them or not.
// Except when -Zquery-dep-graph is specified because we don't
// want to mess up our tests.
let hcx = if tcx.sess.opts.debugging_opts.query_dep_graph {
StableHashingContext::new(tcx)
} else {
StableHashingContext::new(tcx).force_span_hashing()
};
Some((hcx, StableHasher::new()))
} else {
None
}
......
......@@ -103,18 +103,11 @@ fn read_file(&self, path: &Path) -> io::Result<String> {
//
pub struct CodeMap {
// The `files` field should not be visible outside of libsyntax so that we
// can do proper dependency tracking.
pub(super) files: RefCell<Vec<Rc<FileMap>>>,
file_loader: Box<FileLoader>,
// This is used to apply the file path remapping as specified via
// -Zremap-path-prefix to all FileMaps allocated within this CodeMap.
path_mapping: FilePathMapping,
// The CodeMap will invoke this callback whenever a specific FileMap is
// accessed. The callback starts out as a no-op but when the dependency
// graph becomes available later during the compilation process, it is
// be replaced with something that notifies the dep-tracking system.
dep_tracking_callback: RefCell<Box<Fn(&FileMap)>>,
}
impl CodeMap {
......@@ -123,7 +116,6 @@ pub fn new(path_mapping: FilePathMapping) -> CodeMap {
files: RefCell::new(Vec::new()),
file_loader: Box::new(RealFileLoader),
path_mapping: path_mapping,
dep_tracking_callback: RefCell::new(Box::new(|_| {})),
}
}
......@@ -134,7 +126,6 @@ pub fn with_file_loader(file_loader: Box<FileLoader>,
files: RefCell::new(Vec::new()),
file_loader: file_loader,
path_mapping: path_mapping,
dep_tracking_callback: RefCell::new(Box::new(|_| {})),
}
}
......@@ -142,10 +133,6 @@ pub fn path_mapping(&self) -> &FilePathMapping {
&self.path_mapping
}
pub fn set_dep_tracking_callback(&self, cb: Box<Fn(&FileMap)>) {
*self.dep_tracking_callback.borrow_mut() = cb;
}
pub fn file_exists(&self, path: &Path) -> bool {
self.file_loader.file_exists(path)
}
......@@ -156,15 +143,6 @@ pub fn load_file(&self, path: &Path) -> io::Result<Rc<FileMap>> {
}
pub fn files(&self) -> Ref<Vec<Rc<FileMap>>> {
let files = self.files.borrow();
for file in files.iter() {
(self.dep_tracking_callback.borrow())(file);
}
files
}
/// Only use this if you do your own dependency tracking!
pub fn files_untracked(&self) -> Ref<Vec<Rc<FileMap>>> {
self.files.borrow()
}
......@@ -311,8 +289,6 @@ fn lookup_line(&self, pos: BytePos) -> Result<FileMapAndLine, Rc<FileMap>> {
let files = self.files.borrow();
let f = (*files)[idx].clone();
(self.dep_tracking_callback.borrow())(&f);
match f.lookup_line(pos) {
Some(line) => Ok(FileMapAndLine { fm: f, line: line }),
None => Err(f)
......@@ -502,7 +478,6 @@ pub fn def_span(&self, sp: Span) -> Span {
pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
for fm in self.files.borrow().iter() {
if filename == fm.name {
(self.dep_tracking_callback.borrow())(fm);
return Some(fm.clone());
}
}
......@@ -513,7 +488,6 @@ pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
let idx = self.lookup_filemap_idx(bpos);
let fm = (*self.files.borrow())[idx].clone();
(self.dep_tracking_callback.borrow())(&fm);
let offset = bpos - fm.start_pos;
FileMapAndBytePos {fm: fm, pos: offset}
}
......@@ -524,8 +498,6 @@ pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
let files = self.files.borrow();
let map = &(*files)[idx];
(self.dep_tracking_callback.borrow())(map);
// The number of extra bytes due to multibyte chars in the FileMap
let mut total_extra_bytes = 0;
......
......@@ -9,6 +9,7 @@
// except according to those terms.
// no-prefer-dynamic
// compile-flags: -Z query-dep-graph
#![crate_type="rlib"]
......
......@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Z query-dep-graph
#![crate_type="rlib"]
#[cfg(rpass1)]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册