From edc1ac3016d0e8383e174312db7c3b7a885af0c3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 3 Apr 2017 19:20:26 +0200 Subject: [PATCH 1/2] ICH: Centrally compute and cache DefPath hashes as part of DefPathTable. --- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/map/def_collector.rs | 19 +-- src/librustc/hir/map/definitions.rs | 115 ++++++++++++++---- src/librustc/ich/def_path_hash.rs | 36 ------ src/librustc/ich/hcx.rs | 6 +- src/librustc/ich/mod.rs | 2 - src/librustc/middle/cstore.rs | 4 + src/librustc/ty/mod.rs | 9 ++ src/librustc/ty/util.rs | 14 +-- src/librustc_driver/driver.rs | 8 +- src/librustc_incremental/persist/directory.rs | 4 - src/librustc_incremental/persist/save.rs | 13 +- src/librustc_metadata/cstore_impl.rs | 6 +- src/librustc_metadata/decoder.rs | 13 +- src/librustc_resolve/lib.rs | 4 +- src/librustc_trans/back/symbol_names.rs | 25 ++-- src/librustc_typeck/collect.rs | 2 +- 17 files changed, 152 insertions(+), 130 deletions(-) delete mode 100644 src/librustc/ich/def_path_hash.rs diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 17185a6ab69f4..3f4390536b042 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2697,7 +2697,7 @@ impl<'a> LoweringContext<'a> { fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode) -> P { let id = self.next_id(); - let parent_def = self.parent_def; + let parent_def = self.parent_def.unwrap(); let def_id = { let defs = self.resolver.definitions(); let def_path_data = DefPathData::Binding(name.as_str()); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index afdb9059ea7c0..c1417f718b27a 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -40,11 +40,9 @@ impl<'a> DefCollector<'a> { } } - pub fn collect_root(&mut self) { - let root = self.create_def_with_parent(None, - CRATE_NODE_ID, - DefPathData::CrateRoot, - ITEM_LIKE_SPACE); + pub fn collect_root(&mut self, crate_name: &str, crate_disambiguator: &str) { + let root = self.definitions.create_root_def(crate_name, + crate_disambiguator); assert_eq!(root, CRATE_DEF_INDEX); self.parent_def = Some(root); } @@ -54,20 +52,11 @@ impl<'a> DefCollector<'a> { data: DefPathData, address_space: DefIndexAddressSpace) -> DefIndex { - let parent_def = self.parent_def; + let parent_def = self.parent_def.unwrap(); debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); self.definitions.create_def_with_parent(parent_def, node_id, data, address_space) } - fn create_def_with_parent(&mut self, - parent: Option, - node_id: NodeId, - data: DefPathData, - address_space: DefIndexAddressSpace) - -> DefIndex { - self.definitions.create_def_with_parent(parent, node_id, data, address_space) - } - pub fn with_parent(&mut self, parent_def: DefIndex, f: F) { let parent = self.parent_def; self.parent_def = Some(parent_def); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index dca9ebb3397a6..6118df2ddfc89 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -21,7 +21,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::stable_hasher::StableHasher; use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::fmt::Write; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use syntax::ast; use syntax::symbol::{Symbol, InternedString}; use ty::TyCtxt; @@ -34,6 +34,7 @@ use util::nodemap::NodeMap; pub struct DefPathTable { index_to_key: [Vec; 2], key_to_index: FxHashMap, + def_path_hashes: [Vec; 2], } // Unfortunately we have to provide a manual impl of Clone because of the @@ -44,6 +45,8 @@ impl Clone for DefPathTable { index_to_key: [self.index_to_key[0].clone(), self.index_to_key[1].clone()], key_to_index: self.key_to_index.clone(), + def_path_hashes: [self.def_path_hashes[0].clone(), + self.def_path_hashes[1].clone()], } } } @@ -52,6 +55,7 @@ impl DefPathTable { fn allocate(&mut self, key: DefKey, + def_path_hash: u64, address_space: DefIndexAddressSpace) -> DefIndex { let index = { @@ -62,6 +66,9 @@ impl DefPathTable { index }; self.key_to_index.insert(key, index); + self.def_path_hashes[address_space.index()].push(def_path_hash); + debug_assert!(self.def_path_hashes[address_space.index()].len() == + self.index_to_key[address_space.index()].len()); index } @@ -71,6 +78,12 @@ impl DefPathTable { [index.as_array_index()].clone() } + #[inline(always)] + pub fn def_path_hash(&self, index: DefIndex) -> u64 { + self.def_path_hashes[index.address_space().index()] + [index.as_array_index()] + } + #[inline(always)] pub fn def_index_for_def_key(&self, key: &DefKey) -> Option { self.key_to_index.get(key).cloned() @@ -116,17 +129,28 @@ impl DefPathTable { impl Encodable for DefPathTable { fn encode(&self, s: &mut S) -> Result<(), S::Error> { + // Index to key self.index_to_key[DefIndexAddressSpace::Low.index()].encode(s)?; - self.index_to_key[DefIndexAddressSpace::High.index()].encode(s) + self.index_to_key[DefIndexAddressSpace::High.index()].encode(s)?; + + // DefPath hashes + self.def_path_hashes[DefIndexAddressSpace::Low.index()].encode(s)?; + self.def_path_hashes[DefIndexAddressSpace::High.index()].encode(s)?; + + Ok(()) } } impl Decodable for DefPathTable { fn decode(d: &mut D) -> Result { let index_to_key_lo: Vec = Decodable::decode(d)?; - let index_to_key_high: Vec = Decodable::decode(d)?; + let index_to_key_hi: Vec = Decodable::decode(d)?; - let index_to_key = [index_to_key_lo, index_to_key_high]; + let def_path_hashes_lo: Vec = Decodable::decode(d)?; + let def_path_hashes_hi: Vec = Decodable::decode(d)?; + + let index_to_key = [index_to_key_lo, index_to_key_hi]; + let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi]; let mut key_to_index = FxHashMap(); @@ -141,6 +165,7 @@ impl Decodable for DefPathTable { Ok(DefPathTable { index_to_key: index_to_key, key_to_index: key_to_index, + def_path_hashes: def_path_hashes, }) } } @@ -184,6 +209,29 @@ pub struct DefKey { pub disambiguated_data: DisambiguatedDefPathData, } +impl DefKey { + fn compute_stable_hash(&self, parent_hash: u64) -> u64 { + let mut hasher = StableHasher::new(); + + // We hash a 0u8 here to disambiguate between regular DefPath hashes, + // and the special "root_parent" below. + 0u8.hash(&mut hasher); + parent_hash.hash(&mut hasher); + self.disambiguated_data.hash(&mut hasher); + hasher.finish() + } + + fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 { + let mut hasher = StableHasher::new(); + // Disambiguate this from a regular DefPath hash, + // see compute_stable_hash() above. + 1u8.hash(&mut hasher); + crate_name.hash(&mut hasher); + crate_disambiguator.hash(&mut hasher); + hasher.finish() + } +} + /// Pair of `DefPathData` and an integer disambiguator. The integer is /// normally 0, but in the event that there are multiple defs with the /// same `parent` and `data`, we use this field to disambiguate @@ -271,19 +319,6 @@ impl DefPath { s } - - pub fn deterministic_hash(&self, tcx: TyCtxt) -> u64 { - debug!("deterministic_hash({:?})", self); - let mut state = StableHasher::new(); - self.deterministic_hash_to(tcx, &mut state); - state.finish() - } - - pub fn deterministic_hash_to(&self, tcx: TyCtxt, state: &mut H) { - tcx.original_crate_name(self.krate).as_str().hash(state); - tcx.crate_disambiguator(self.krate).as_str().hash(state); - self.data.hash(state); - } } #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] @@ -338,6 +373,7 @@ impl Definitions { table: DefPathTable { index_to_key: [vec![], vec![]], key_to_index: FxHashMap(), + def_path_hashes: [vec![], vec![]], }, node_to_def_index: NodeMap(), def_index_to_node: [vec![], vec![]], @@ -359,6 +395,11 @@ impl Definitions { self.table.def_key(index) } + #[inline(always)] + pub fn def_path_hash(&self, index: DefIndex) -> u64 { + self.table.def_path_hash(index) + } + pub fn def_index_for_def_key(&self, key: DefKey) -> Option { self.table.def_index_for_def_key(&key) } @@ -398,12 +439,38 @@ impl Definitions { self.node_to_hir_id[node_id] } + /// Add a definition with a parent definition. + pub fn create_root_def(&mut self, + crate_name: &str, + crate_disambiguator: &str) + -> DefIndex { + let key = DefKey { + parent: None, + disambiguated_data: DisambiguatedDefPathData { + data: DefPathData::CrateRoot, + disambiguator: 0 + } + }; + + let parent_hash = DefKey::root_parent_stable_hash(crate_name, + crate_disambiguator); + let def_path_hash = key.compute_stable_hash(parent_hash); + + // Create the definition. + let address_space = super::ITEM_LIKE_SPACE; + let index = self.table.allocate(key, def_path_hash, address_space); + assert!(self.def_index_to_node[address_space.index()].is_empty()); + self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID); + self.node_to_def_index.insert(ast::CRATE_NODE_ID, index); + + index + } + /// Add a definition with a parent definition. pub fn create_def_with_parent(&mut self, - parent: Option, + parent: DefIndex, node_id: ast::NodeId, data: DefPathData, - // is_owner: bool) address_space: DefIndexAddressSpace) -> DefIndex { debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})", @@ -415,12 +482,13 @@ impl Definitions { data, self.table.def_key(self.node_to_def_index[&node_id])); - assert_eq!(parent.is_some(), data != DefPathData::CrateRoot); + // The root node must be created with create_root_def() + assert!(data != DefPathData::CrateRoot); // Find a unique DefKey. This basically means incrementing the disambiguator // until we get no match. let mut key = DefKey { - parent: parent, + parent: Some(parent), disambiguated_data: DisambiguatedDefPathData { data: data, disambiguator: 0 @@ -431,10 +499,13 @@ impl Definitions { key.disambiguated_data.disambiguator += 1; } + let parent_hash = self.table.def_path_hash(parent); + let def_path_hash = key.compute_stable_hash(parent_hash); + debug!("create_def_with_parent: after disambiguation, key = {:?}", key); // Create the definition. - let index = self.table.allocate(key, address_space); + let index = self.table.allocate(key, def_path_hash, address_space); assert_eq!(index.as_array_index(), self.def_index_to_node[address_space.index()].len()); self.def_index_to_node[address_space.index()].push(node_id); diff --git a/src/librustc/ich/def_path_hash.rs b/src/librustc/ich/def_path_hash.rs deleted file mode 100644 index 03051dc003420..0000000000000 --- a/src/librustc/ich/def_path_hash.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012-2014 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 hir::def_id::DefId; -use ty::TyCtxt; -use util::nodemap::DefIdMap; - -pub struct DefPathHashes<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - data: DefIdMap, -} - -impl<'a, 'tcx> DefPathHashes<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { - DefPathHashes { - tcx: tcx, - data: DefIdMap() - } - } - - pub fn hash(&mut self, def_id: DefId) -> u64 { - let tcx = self.tcx; - *self.data.entry(def_id) - .or_insert_with(|| { - let def_path = tcx.def_path(def_id); - def_path.deterministic_hash(tcx) - }) - } -} diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 73d81212cd77e..5ef30550f1155 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -10,7 +10,7 @@ use hir; use hir::def_id::DefId; -use ich::{self, CachingCodemapView, DefPathHashes}; +use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; use ty; @@ -32,7 +32,6 @@ use rustc_data_structures::accumulate_vec::AccumulateVec; /// things (e.g. each DefId/DefPath is only hashed once). pub struct StableHashingContext<'a, 'tcx: 'a> { tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - def_path_hashes: DefPathHashes<'a, 'tcx>, codemap: CachingCodemapView<'tcx>, hash_spans: bool, hash_bodies: bool, @@ -64,7 +63,6 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> { StableHashingContext { tcx: tcx, - def_path_hashes: DefPathHashes::new(tcx), codemap: CachingCodemapView::new(tcx), hash_spans: hash_spans_initial, hash_bodies: true, @@ -111,7 +109,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> { #[inline] pub fn def_path_hash(&mut self, def_id: DefId) -> u64 { - self.def_path_hashes.hash(def_id) + self.tcx.def_path_hash(def_id) } #[inline] diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index f0601a0efabf8..f932c90a331e1 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -11,12 +11,10 @@ //! ICH - Incremental Compilation Hash pub use self::fingerprint::Fingerprint; -pub use self::def_path_hash::DefPathHashes; pub use self::caching_codemap_view::CachingCodemapView; pub use self::hcx::{StableHashingContext, NodeIdHashingMode}; mod fingerprint; -mod def_path_hash; mod caching_codemap_view; mod hcx; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 8bc0cf2577b5d..ee0635ac9a179 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -230,6 +230,7 @@ pub trait CrateStore { -> Option; fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; + fn def_path_hash(&self, def: DefId) -> u64; fn struct_field_names(&self, def: DefId) -> Vec; fn item_children(&self, did: DefId) -> Vec; fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; @@ -377,6 +378,9 @@ impl CrateStore for DummyCrateStore { fn def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") } + fn def_path_hash(&self, def: DefId) -> u64 { + bug!("wa") + } fn struct_field_names(&self, def: DefId) -> Vec { bug!("struct_field_names") } fn item_children(&self, did: DefId) -> Vec { bug!("item_children") } fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3c529a6982042..292e30e3d41f1 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2227,6 +2227,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + #[inline] + pub fn def_path_hash(self, def_id: DefId) -> u64 { + if def_id.is_local() { + self.hir.definitions().def_path_hash(def_id.index) + } else { + self.sess.cstore.def_path_hash(def_id) + } + } + pub fn def_span(self, def_id: DefId) -> Span { if let Some(id) = self.hir.as_local_node_id(def_id) { self.hir.span(id) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 1c1e0d91cb4d6..fd8191303a9a6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -13,7 +13,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use hir::map::DefPathData; use infer::InferCtxt; -use hir::map as hir_map; +// use hir::map as hir_map; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; use ty::ParameterEnvironment; @@ -441,13 +441,11 @@ impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W> fn def_id(&mut self, did: DefId) { // Hash the DefPath corresponding to the DefId, which is independent - // of compiler internal state. - let path = self.tcx.def_path(did); - self.def_path(&path) - } - - pub fn def_path(&mut self, def_path: &hir_map::DefPath) { - def_path.deterministic_hash_to(self.tcx, &mut self.state); + // of compiler internal state. We already have a stable hash value of + // all DefPaths available via tcx.def_path_hash(), so we just feed that + // into the hasher. + let hash = self.tcx.def_path_hash(did); + self.hash(hash); } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 96eb5dd602f51..4e6c919c7f569 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -647,8 +647,12 @@ pub fn phase_2_configure_and_expand(sess: &Session, let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name); crate_loader.preprocess(&krate); let resolver_arenas = Resolver::arenas(); - let mut resolver = - Resolver::new(sess, &krate, make_glob_map, &mut crate_loader, &resolver_arenas); + let mut resolver = Resolver::new(sess, + &krate, + crate_name, + make_glob_map, + &mut crate_loader, + &resolver_arenas); resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives; syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features.borrow().quote); diff --git a/src/librustc_incremental/persist/directory.rs b/src/librustc_incremental/persist/directory.rs index 546feb212243a..b9b860222968b 100644 --- a/src/librustc_incremental/persist/directory.rs +++ b/src/librustc_incremental/persist/directory.rs @@ -186,10 +186,6 @@ impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> { .clone() } - pub fn lookup_def_path(&self, id: DefPathIndex) -> &DefPath { - &self.directory.paths[id.index as usize] - } - pub fn map(&mut self, node: &DepNode) -> DepNode { node.map_def(|&def_id| Some(self.add(def_id))).unwrap() } diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 2e5186493370b..1591503865e81 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -258,8 +258,6 @@ pub fn encode_metadata_hashes(tcx: TyCtxt, index_map: FxHashMap() }; - let mut def_id_hashes = FxHashMap(); - for (index, target) in preds.reduced_graph.all_nodes().iter().enumerate() { let index = NodeIndex(index); let def_id = match *target.data { @@ -267,15 +265,6 @@ pub fn encode_metadata_hashes(tcx: TyCtxt, _ => continue, }; - let mut def_id_hash = |def_id: DefId| -> u64 { - *def_id_hashes.entry(def_id) - .or_insert_with(|| { - let index = builder.add(def_id); - let path = builder.lookup_def_path(index); - path.deterministic_hash(tcx) - }) - }; - // To create the hash for each item `X`, we don't hash the raw // bytes of the metadata (though in principle we // could). Instead, we walk the predecessors of `MetaData(X)` @@ -295,7 +284,7 @@ pub fn encode_metadata_hashes(tcx: TyCtxt, .map(|index| preds.reduced_graph.node_data(index)) .filter(|dep_node| HashContext::is_hashable(dep_node)) .map(|dep_node| { - let hash_dep_node = dep_node.map_def(|&def_id| Some(def_id_hash(def_id))) + let hash_dep_node = dep_node.map_def(|&def_id| Some(tcx.def_path_hash(def_id))) .unwrap(); let hash = preds.hashes[dep_node]; (hash_dep_node, hash) diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 41a2e8a8d55e3..efcd2f007d66c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -73,7 +73,7 @@ provide! { <'tcx> tcx, def_id, cdata predicates => { cdata.get_predicates(def_id.index, tcx) } super_predicates => { cdata.get_super_predicates(def_id.index, tcx) } trait_def => { - tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx)) + tcx.alloc_trait_def(cdata.get_trait_def(def_id.index)) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { @@ -370,6 +370,10 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path(def.index) } + fn def_path_hash(&self, def: DefId) -> u64 { + self.get_crate_data(def.krate).def_path_hash(def.index) + } + fn struct_field_names(&self, def: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def)); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 43e076e799b3d..cdbecb3ae2e42 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -492,10 +492,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_trait_def(&self, - item_id: DefIndex, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> ty::TraitDef { + pub fn get_trait_def(&self, item_id: DefIndex) -> ty::TraitDef { let data = match self.entry(item_id).kind { EntryKind::Trait(data) => data.decode(self), _ => bug!(), @@ -504,7 +501,7 @@ impl<'a, 'tcx> CrateMetadata { let def = ty::TraitDef::new(self.local_def_id(item_id), data.unsafety, data.paren_sugar, - self.def_path(item_id).deterministic_hash(tcx)); + self.def_path_table.def_path_hash(item_id)); if data.has_default_impl { def.record_has_default_impl(); @@ -1053,6 +1050,7 @@ impl<'a, 'tcx> CrateMetadata { } } + #[inline] pub fn def_key(&self, index: DefIndex) -> DefKey { self.def_path_table.def_key(index) } @@ -1063,6 +1061,11 @@ impl<'a, 'tcx> CrateMetadata { DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent)) } + #[inline] + pub fn def_path_hash(&self, index: DefIndex) -> u64 { + self.def_path_table.def_path_hash(index) + } + /// Imports the codemap from an external crate into the codemap of the crate /// currently being compiled (the "local crate"). /// diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0466e76475da3..d9900340a2e9f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1289,6 +1289,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { impl<'a> Resolver<'a> { pub fn new(session: &'a Session, krate: &Crate, + crate_name: &str, make_glob_map: MakeGlobMap, crate_loader: &'a mut CrateLoader, arenas: &'a ResolverArenas<'a>) @@ -1303,7 +1304,8 @@ impl<'a> Resolver<'a> { module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root); let mut definitions = Definitions::new(); - DefCollector::new(&mut definitions).collect_root(); + DefCollector::new(&mut definitions) + .collect_root(crate_name, &session.local_crate_disambiguator().as_str()); let mut invocations = FxHashMap(); invocations.insert(Mark::root(), diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 3ad04e10cb027..3568c1ba8f4c1 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -101,13 +101,13 @@ use common::SharedCrateContext; use monomorphize::Instance; use rustc::middle::weak_lang_items; -use rustc::hir::def_id::LOCAL_CRATE; +use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::fold::TypeVisitor; use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; use rustc::ty::subst::Substs; -use rustc::hir::map::definitions::{DefPath, DefPathData}; +use rustc::hir::map::definitions::DefPathData; use rustc::util::common::record_time; use syntax::attr; @@ -115,8 +115,8 @@ use syntax::symbol::{Symbol, InternedString}; fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - // path to the item this name is for - def_path: &DefPath, + // the DefId of the item this name is for + def_id: Option, // type of the item, without any generic // parameters substituted; this is @@ -128,8 +128,7 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, // if any. substs: Option<&'tcx Substs<'tcx>>) -> String { - debug!("get_symbol_hash(def_path={:?}, parameters={:?})", - def_path, substs); + debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs); let tcx = scx.tcx(); @@ -139,7 +138,7 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, // the main symbol name is not necessarily unique; hash in the // compiler's internal def-path, guaranteeing each symbol has a // truly unique path - hasher.def_path(def_path); + hasher.hash(def_id.map(|def_id| tcx.def_path_hash(def_id))); // Include the main item-type. Note that, in this case, the // assertions about `needs_subst` may not hold, but this item-type @@ -224,8 +223,6 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>, return scx.tcx().item_name(def_id).as_str().to_string(); } - let def_path = scx.tcx().def_path(def_id); - // We want to compute the "type" of this item. Unfortunately, some // kinds of items (e.g., closures) don't have an entry in the // item-type array. So walk back up the find the closest parent @@ -256,10 +253,10 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>, // and should not matter anyhow. let instance_ty = scx.tcx().erase_regions(&instance_ty); - let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs)); + let hash = get_symbol_hash(scx, Some(def_id), instance_ty, Some(substs)); let mut buffer = SymbolPathBuffer { - names: Vec::with_capacity(def_path.data.len()) + names: Vec::new() }; item_path::with_forced_absolute_paths(|| { @@ -288,11 +285,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, t: Ty<'tcx>, prefix: &str) -> String { - let empty_def_path = DefPath { - data: vec![], - krate: LOCAL_CRATE, - }; - let hash = get_symbol_hash(scx, &empty_def_path, t, None); + let hash = get_symbol_hash(scx, None, t, None); let path = [Symbol::intern(prefix).as_str()]; mangle(path.iter().cloned(), &hash) } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1ed42b842c6fa..77ab076eba386 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -806,7 +806,7 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, err.emit(); } - let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx); + let def_path_hash = tcx.def_path_hash(def_id); let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash); if tcx.hir.trait_is_auto(def_id) { From bb6387295a85da70546ed3ce7fa0d702b9cb9d6c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 3 Apr 2017 19:39:12 +0200 Subject: [PATCH 2/2] SVH: Don't hash the HIR twice when once is enough. The SVH (Strict Version Hash) of a crate is currently computed by hashing the ICHes (Incremental Computation Hashes) of the crate's HIR. This is fine, expect that for incr. comp. we compute two ICH values for each HIR item, one for the complete item and one that just includes the item's interface. The two hashes are are needed for dependency tracking but if we are compiling non-incrementally and just need the ICH values for the SVH, one of them is enough, giving us the opportunity to save some work in this case. --- src/librustc_incremental/calculate_svh/mod.rs | 9 ++++++++- src/librustc_incremental/lib.rs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index c80a5a1627797..c67866971e199 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -99,6 +99,13 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { item_like: T) where T: HashStable> { + if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() { + // If we just need the hashes in order to compute the SVH, we don't + // need have two hashes per item. Just the one containing also the + // item's body is sufficient. + return + } + let mut hasher = IchHasher::new(); self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| { item_like.hash_stable(hcx, &mut hasher); @@ -143,7 +150,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { (item_dep_node, item_hash) }) .collect(); - item_hashes.sort(); // avoid artificial dependencies on item ordering + item_hashes.sort_unstable(); // avoid artificial dependencies on item ordering item_hashes.hash(&mut crate_state); } diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index d10df17f85837..aa7eb36581f3e 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -23,6 +23,7 @@ #![feature(staged_api)] #![feature(rand)] #![feature(conservative_impl_trait)] +#![feature(sort_unstable)] #![cfg_attr(stage0, feature(pub_restricted))] extern crate graphviz;