Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle DefPath hashing centrally as part of DefPathTable (+ save work during SVH calculation) #41056

Merged
merged 2 commits into from
Apr 7, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -2697,7 +2697,7 @@ impl<'a> LoweringContext<'a> {
fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
-> P<hir::Pat> {
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());
19 changes: 4 additions & 15 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
@@ -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<DefIndex>,
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<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
let parent = self.parent_def;
self.parent_def = Some(parent_def);
115 changes: 93 additions & 22 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
@@ -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<DefKey>; 2],
key_to_index: FxHashMap<DefKey, DefIndex>,
def_path_hashes: [Vec<u64>; 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<DefIndex> {
self.key_to_index.get(key).cloned()
@@ -116,17 +129,28 @@ impl DefPathTable {

impl Encodable for DefPathTable {
fn encode<S: Encoder>(&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: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key_high: Vec<DefKey> = Decodable::decode(d)?;
let index_to_key_hi: Vec<DefKey> = Decodable::decode(d)?;

let index_to_key = [index_to_key_lo, index_to_key_high];
let def_path_hashes_lo: Vec<u64> = Decodable::decode(d)?;
let def_path_hashes_hi: Vec<u64> = 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<H: Hasher>(&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<DefIndex> {
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<DefIndex>,
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);
36 changes: 0 additions & 36 deletions src/librustc/ich/def_path_hash.rs

This file was deleted.

6 changes: 2 additions & 4 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
@@ -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]
2 changes: 0 additions & 2 deletions src/librustc/ich/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

4 changes: 4 additions & 0 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
@@ -230,6 +230,7 @@ pub trait CrateStore {
-> Option<DefId>;
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<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<def::Export>;
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<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }
Loading