Skip to content

Commit

Permalink
incr.comp.: Hash more pieces of crate metadata to detect changes there.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed May 8, 2017
1 parent 70198a0 commit 6a5e2a5
Show file tree
Hide file tree
Showing 32 changed files with 1,500 additions and 851 deletions.
21 changes: 19 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub enum DepNode<D: Clone + Debug> {
// in an extern crate.
MetaData(D),

// Represents some piece of metadata global to its crate.
GlobalMetaData(D, GlobalMetaDataKind),

// Represents some artifact that we save to disk. Note that these
// do not have a def-id as part of their identifier.
WorkProduct(Arc<WorkProductId>),
Expand Down Expand Up @@ -79,7 +82,6 @@ pub enum DepNode<D: Clone + Debug> {
MirKeys,
LateLintCheck,
TransCrateItem(D),
TransInlinedItem(D),
TransWriteMetadata,
CrateVariances,

Expand Down Expand Up @@ -157,6 +159,7 @@ pub enum DepNode<D: Clone + Debug> {
DefSpan(D),
Stability(D),
Deprecation(D),
FileMap(D, Arc<String>),
}

impl<D: Clone + Debug> DepNode<D> {
Expand Down Expand Up @@ -234,7 +237,6 @@ impl<D: Clone + Debug> DepNode<D> {
RegionMaps(ref d) => op(d).map(RegionMaps),
RvalueCheck(ref d) => op(d).map(RvalueCheck),
TransCrateItem(ref d) => op(d).map(TransCrateItem),
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
AssociatedItems(ref d) => op(d).map(AssociatedItems),
ItemSignature(ref d) => op(d).map(ItemSignature),
ItemVariances(ref d) => op(d).map(ItemVariances),
Expand Down Expand Up @@ -271,6 +273,8 @@ impl<D: Clone + Debug> DepNode<D> {
DefSpan(ref d) => op(d).map(DefSpan),
Stability(ref d) => op(d).map(Stability),
Deprecation(ref d) => op(d).map(Deprecation),
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())),
}
}
}
Expand All @@ -282,3 +286,16 @@ impl<D: Clone + Debug> DepNode<D> {
/// them even in the absence of a tcx.)
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct WorkProductId(pub String);

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
Krate,
CrateDeps,
DylibDependencyFormats,
LangItems,
LangItemsMissing,
NativeLibraries,
CodeMap,
Impls,
ExportedSymbols,
}
1 change: 1 addition & 0 deletions src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod thread;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::DepNode;
pub use self::dep_node::WorkProductId;
pub use self::dep_node::GlobalMetaDataKind;
pub use self::graph::DepGraph;
pub use self::graph::WorkProduct;
pub use self::query::DepGraphQuery;
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/hir/svh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ impl Decodable for Svh {
.map(Svh::new)
}
}

impl_stable_hash_for!(struct Svh {
hash
});
35 changes: 32 additions & 3 deletions src/librustc/ich/caching_codemap_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ty::TyCtxt;
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;

#[derive(Clone)]
struct CacheEntry {
Expand All @@ -20,30 +24,37 @@ struct CacheEntry {
line_start: BytePos,
line_end: BytePos,
file: Rc<FileMap>,
file_index: usize,
}

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 first_file = codemap.files.borrow()[0].clone();
let files = codemap.files_untracked();
let first_file = files[0].clone();
let entry = CacheEntry {
time_stamp: 0,
line_number: 0,
line_start: BytePos(0),
line_end: BytePos(0),
file: first_file,
file_index: 0,
};

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()),
}
}

Expand All @@ -56,6 +67,10 @@ impl<'tcx> CachingCodemapView<'tcx> {
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,
pos - cache_entry.line_start));
Expand All @@ -75,14 +90,15 @@ impl<'tcx> CachingCodemapView<'tcx> {
// 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.borrow();
let files = self.codemap.files_untracked();

if files.len() > 0 {
let file_index = self.codemap.lookup_filemap_idx(pos);
let file = files[file_index].clone();

if pos >= file.start_pos && pos < file.end_pos {
cache_entry.file = file;
cache_entry.file_index = file_index;
file_valid = true;
} else {
file_valid = false;
Expand All @@ -104,8 +120,21 @@ impl<'tcx> CachingCodemapView<'tcx> {
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)
}
40 changes: 40 additions & 0 deletions src/librustc/ich/impls_cstore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains `HashStable` implementations for various data types
//! from rustc::middle::cstore in no particular order.

use middle;

impl_stable_hash_for!(enum middle::cstore::DepKind {
UnexportedMacrosOnly,
MacrosOnly,
Implicit,
Explicit
});

impl_stable_hash_for!(enum middle::cstore::NativeLibraryKind {
NativeStatic,
NativeStaticNobundle,
NativeFramework,
NativeUnknown
});

impl_stable_hash_for!(struct middle::cstore::NativeLibrary {
kind,
name,
cfg,
foreign_items
});

impl_stable_hash_for!(enum middle::cstore::LinkagePreference {
RequireDynamic,
RequireStatic
});
8 changes: 8 additions & 0 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,3 +1120,11 @@ impl_stable_hash_for!(struct hir::def::Export {
def,
span
});

impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::lang_items::LangItem {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
::std::hash::Hash::hash(self, hasher);
}
}
80 changes: 79 additions & 1 deletion src/librustc/ich/impls_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ use std::mem;
use syntax::ast;
use syntax::parse::token;
use syntax::tokenstream;
use syntax_pos::Span;
use syntax_pos::{Span, FileMap};

use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
Expand Down Expand Up @@ -299,3 +301,79 @@ fn hash_token<'a, 'tcx, W: StableHasherResult>(token: &token::Token,
token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
}
}

impl_stable_hash_for_spanned!(::syntax::ast::NestedMetaItemKind);

impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
MetaItem(meta_item),
Literal(lit)
});

impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
name,
node,
span
});

impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind {
Word,
List(nested_items),
NameValue(lit)
});

impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for FileMap {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
let FileMap {
ref name,
name_was_remapped,
crate_of_origin,
// Do not hash the source as it is not encoded
src: _,
start_pos,
end_pos: _,
ref lines,
ref multibyte_chars,
} = *self;

name.hash_stable(hcx, hasher);
name_was_remapped.hash_stable(hcx, hasher);

DefId {
krate: CrateNum::from_u32(crate_of_origin),
index: CRATE_DEF_INDEX,
}.hash_stable(hcx, hasher);

// We only hash the relative position within this filemap
let lines = lines.borrow();
lines.len().hash_stable(hcx, hasher);
for &line in lines.iter() {
stable_byte_pos(line, start_pos).hash_stable(hcx, hasher);
}

// We only hash the relative position within this filemap
let multibyte_chars = multibyte_chars.borrow();
multibyte_chars.len().hash_stable(hcx, hasher);
for &char_pos in multibyte_chars.iter() {
stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher);
}
}
}

fn stable_byte_pos(pos: ::syntax_pos::BytePos,
filemap_start: ::syntax_pos::BytePos)
-> u32 {
pos.0 - filemap_start.0
}

fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar,
filemap_start: ::syntax_pos::BytePos)
-> (u32, u32) {
let ::syntax_pos::MultiByteChar {
pos,
bytes,
} = mbc;

(pos.0 - filemap_start.0, bytes as u32)
}
1 change: 1 addition & 0 deletions src/librustc/ich/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod caching_codemap_view;
mod hcx;

mod impls_const_math;
mod impls_cstore;
mod impls_hir;
mod impls_mir;
mod impls_ty;
Expand Down
30 changes: 29 additions & 1 deletion src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
// probably get a better home if someone can find one.

use hir::def;
use dep_graph::DepNode;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::map as hir_map;
use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData};
Expand Down Expand Up @@ -161,7 +162,16 @@ pub struct ExternCrate {

pub struct EncodedMetadata {
pub raw_data: Vec<u8>,
pub hashes: Vec<EncodedMetadataHash>,
pub hashes: EncodedMetadataHashes,
}

impl EncodedMetadata {
pub fn new() -> EncodedMetadata {
EncodedMetadata {
raw_data: Vec::new(),
hashes: EncodedMetadataHashes::new(),
}
}
}

/// The hash for some metadata that (when saving) will be exported
Expand All @@ -173,6 +183,24 @@ pub struct EncodedMetadataHash {
pub hash: ich::Fingerprint,
}

/// The hash for some metadata that (when saving) will be exported
/// from this crate, or which (when importing) was exported by an
/// upstream crate.
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
pub struct EncodedMetadataHashes {
pub entry_hashes: Vec<EncodedMetadataHash>,
pub global_hashes: Vec<(DepNode<()>, ich::Fingerprint)>,
}

impl EncodedMetadataHashes {
pub fn new() -> EncodedMetadataHashes {
EncodedMetadataHashes {
entry_hashes: Vec::new(),
global_hashes: Vec::new(),
}
}
}

/// A store of Rust crates, through with their metadata
/// can be accessed.
pub trait CrateStore {
Expand Down
Loading

0 comments on commit 6a5e2a5

Please sign in to comment.