Skip to content

Commit b6ada54

Browse files
Rollup merge of rust-lang#42082 - michaelwoerister:wider_def_path_hashes, r=eddyb
incr. comp.: Use more bits for DefPath hashes Use 128 instead of 64 bits for DefPath hashes, like we do for everything else. Collision probability is unnecessarily high with 64 bits. Also change the representation of `ich::Fingerprint` from `Fingerprint([u8; 16])` to `Fingerprint(u64, u64)` which is better for hashers like `FxHasher`.
2 parents e528654 + 4549423 commit b6ada54

File tree

10 files changed

+51
-66
lines changed

10 files changed

+51
-66
lines changed

src/librustc/hir/map/definitions.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use hir;
1818
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
19+
use ich::Fingerprint;
1920
use rustc_data_structures::fx::FxHashMap;
2021
use rustc_data_structures::indexed_vec::IndexVec;
2122
use rustc_data_structures::stable_hasher::StableHasher;
@@ -34,7 +35,7 @@ use util::nodemap::NodeMap;
3435
pub struct DefPathTable {
3536
index_to_key: [Vec<DefKey>; 2],
3637
key_to_index: FxHashMap<DefKey, DefIndex>,
37-
def_path_hashes: [Vec<u64>; 2],
38+
def_path_hashes: [Vec<Fingerprint>; 2],
3839
}
3940

4041
// Unfortunately we have to provide a manual impl of Clone because of the
@@ -55,7 +56,7 @@ impl DefPathTable {
5556

5657
fn allocate(&mut self,
5758
key: DefKey,
58-
def_path_hash: u64,
59+
def_path_hash: Fingerprint,
5960
address_space: DefIndexAddressSpace)
6061
-> DefIndex {
6162
let index = {
@@ -79,7 +80,7 @@ impl DefPathTable {
7980
}
8081

8182
#[inline(always)]
82-
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
83+
pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint {
8384
self.def_path_hashes[index.address_space().index()]
8485
[index.as_array_index()]
8586
}
@@ -146,8 +147,8 @@ impl Decodable for DefPathTable {
146147
let index_to_key_lo: Vec<DefKey> = Decodable::decode(d)?;
147148
let index_to_key_hi: Vec<DefKey> = Decodable::decode(d)?;
148149

149-
let def_path_hashes_lo: Vec<u64> = Decodable::decode(d)?;
150-
let def_path_hashes_hi: Vec<u64> = Decodable::decode(d)?;
150+
let def_path_hashes_lo: Vec<Fingerprint> = Decodable::decode(d)?;
151+
let def_path_hashes_hi: Vec<Fingerprint> = Decodable::decode(d)?;
151152

152153
let index_to_key = [index_to_key_lo, index_to_key_hi];
153154
let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi];
@@ -210,7 +211,7 @@ pub struct DefKey {
210211
}
211212

212213
impl DefKey {
213-
fn compute_stable_hash(&self, parent_hash: u64) -> u64 {
214+
fn compute_stable_hash(&self, parent_hash: Fingerprint) -> Fingerprint {
214215
let mut hasher = StableHasher::new();
215216

216217
// We hash a 0u8 here to disambiguate between regular DefPath hashes,
@@ -221,7 +222,7 @@ impl DefKey {
221222
hasher.finish()
222223
}
223224

224-
fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 {
225+
fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> Fingerprint {
225226
let mut hasher = StableHasher::new();
226227
// Disambiguate this from a regular DefPath hash,
227228
// see compute_stable_hash() above.
@@ -396,7 +397,7 @@ impl Definitions {
396397
}
397398

398399
#[inline(always)]
399-
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
400+
pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint {
400401
self.table.def_path_hash(index)
401402
}
402403

src/librustc/ich/fingerprint.rs

+26-46
Original file line numberDiff line numberDiff line change
@@ -10,95 +10,75 @@
1010

1111
use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
1212
use rustc_data_structures::stable_hasher;
13-
use rustc_data_structures::ToHex;
14-
15-
const FINGERPRINT_LENGTH: usize = 16;
13+
use std::mem;
14+
use std::slice;
1615

1716
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
18-
pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]);
17+
pub struct Fingerprint(u64, u64);
1918

2019
impl Fingerprint {
2120
#[inline]
2221
pub fn zero() -> Fingerprint {
23-
Fingerprint([0; FINGERPRINT_LENGTH])
22+
Fingerprint(0, 0)
2423
}
2524

25+
#[inline]
2626
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
27-
let mut result = Fingerprint::zero();
28-
result.0[0] = (hash >> 0) as u8;
29-
result.0[1] = (hash >> 8) as u8;
30-
result.0[2] = (hash >> 16) as u8;
31-
result.0[3] = (hash >> 24) as u8;
32-
result.0[4] = (hash >> 32) as u8;
33-
result.0[5] = (hash >> 40) as u8;
34-
result.0[6] = (hash >> 48) as u8;
35-
result.0[7] = (hash >> 56) as u8;
36-
result
27+
Fingerprint(hash, hash)
3728
}
3829

30+
#[inline]
3931
pub fn to_smaller_hash(&self) -> u64 {
40-
((self.0[0] as u64) << 0) |
41-
((self.0[1] as u64) << 8) |
42-
((self.0[2] as u64) << 16) |
43-
((self.0[3] as u64) << 24) |
44-
((self.0[4] as u64) << 32) |
45-
((self.0[5] as u64) << 40) |
46-
((self.0[6] as u64) << 48) |
47-
((self.0[7] as u64) << 56)
32+
self.0
4833
}
4934

5035
pub fn to_hex(&self) -> String {
51-
self.0.to_hex()
36+
format!("{:x}{:x}", self.0, self.1)
5237
}
5338
}
5439

5540
impl Encodable for Fingerprint {
5641
#[inline]
5742
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
58-
for &byte in &self.0 {
59-
s.emit_u8(byte)?;
60-
}
61-
Ok(())
43+
s.emit_u64(self.0.to_le())?;
44+
s.emit_u64(self.1.to_le())
6245
}
6346
}
6447

6548
impl Decodable for Fingerprint {
6649
#[inline]
6750
fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
68-
let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]);
69-
for byte in &mut result.0 {
70-
*byte = d.read_u8()?;
71-
}
72-
Ok(result)
51+
let _0 = u64::from_le(d.read_u64()?);
52+
let _1 = u64::from_le(d.read_u64()?);
53+
Ok(Fingerprint(_0, _1))
7354
}
7455
}
7556

7657
impl ::std::fmt::Display for Fingerprint {
7758
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
78-
for i in 0 .. self.0.len() {
79-
if i > 0 {
80-
write!(formatter, "::")?;
81-
}
82-
83-
write!(formatter, "{}", self.0[i])?;
84-
}
85-
Ok(())
59+
write!(formatter, "{:x}-{:x}", self.0, self.1)
8660
}
8761
}
8862

89-
9063
impl stable_hasher::StableHasherResult for Fingerprint {
9164
fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
92-
let mut fingerprint = Fingerprint::zero();
93-
fingerprint.0.copy_from_slice(hasher.finalize());
94-
fingerprint
65+
let hash_bytes: &[u8] = hasher.finalize();
66+
67+
assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2);
68+
let hash_bytes: &[u64] = unsafe {
69+
slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2)
70+
};
71+
72+
// The bytes returned bytes the Blake2B hasher are always little-endian.
73+
Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1]))
9574
}
9675
}
9776

9877
impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
78+
#[inline]
9979
fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
10080
_: &mut CTX,
10181
hasher: &mut stable_hasher::StableHasher<W>) {
102-
::std::hash::Hash::hash(&self.0, hasher);
82+
::std::hash::Hash::hash(self, hasher);
10383
}
10484
}

src/librustc/ich/hcx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
110110
}
111111

112112
#[inline]
113-
pub fn def_path_hash(&mut self, def_id: DefId) -> u64 {
113+
pub fn def_path_hash(&mut self, def_id: DefId) -> ich::Fingerprint {
114114
self.tcx.def_path_hash(def_id)
115115
}
116116

src/librustc/middle/cstore.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ pub trait CrateStore {
282282
-> Option<DefId>;
283283
fn def_key(&self, def: DefId) -> DefKey;
284284
fn def_path(&self, def: DefId) -> hir_map::DefPath;
285-
fn def_path_hash(&self, def: DefId) -> u64;
285+
fn def_path_hash(&self, def: DefId) -> ich::Fingerprint;
286286
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
287287
fn item_children(&self, did: DefId) -> Vec<def::Export>;
288288
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
@@ -414,7 +414,7 @@ impl CrateStore for DummyCrateStore {
414414
fn def_path(&self, def: DefId) -> hir_map::DefPath {
415415
bug!("relative_def_path")
416416
}
417-
fn def_path_hash(&self, def: DefId) -> u64 {
417+
fn def_path_hash(&self, def: DefId) -> ich::Fingerprint {
418418
bug!("wa")
419419
}
420420
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }

src/librustc/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use dep_graph::DepNode;
1919
use hir::{map as hir_map, FreevarMap, TraitMap};
2020
use hir::def::{Def, CtorKind, ExportMap};
2121
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
22-
use ich::StableHashingContext;
22+
use ich::{self, StableHashingContext};
2323
use middle::const_val::ConstVal;
2424
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
2525
use middle::privacy::AccessLevels;
@@ -2248,7 +2248,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22482248
}
22492249

22502250
#[inline]
2251-
pub fn def_path_hash(self, def_id: DefId) -> u64 {
2251+
pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint {
22522252
if def_id.is_local() {
22532253
self.hir.definitions().def_path_hash(def_id.index)
22542254
} else {

src/librustc/ty/sty.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use util::nodemap::FxHashMap;
2929
use serialize;
3030

3131
use hir;
32+
use ich;
3233

3334
use self::InferTy::*;
3435
use self::TypeVariants::*;
@@ -849,7 +850,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
849850
self.item_name // safe to skip the binder to access a name
850851
}
851852

852-
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) {
853+
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) {
853854
// We want something here that is stable across crate boundaries.
854855
// The DefId isn't but the `deterministic_hash` of the corresponding
855856
// DefPath is.
@@ -884,7 +885,7 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
884885
self.skip_binder().item_name()
885886
}
886887

887-
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) {
888+
pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) {
888889
self.skip_binder().sort_key(tcx)
889890
}
890891

src/librustc/ty/trait_def.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use hir::def_id::DefId;
12+
use ich::Fingerprint;
1213
use traits::specialization_graph;
1314
use ty::fast_reject;
1415
use ty::fold::TypeFoldable;
@@ -32,7 +33,7 @@ pub struct TraitDef {
3233

3334
/// The ICH of this trait's DefPath, cached here so it doesn't have to be
3435
/// recomputed all the time.
35-
pub def_path_hash: u64,
36+
pub def_path_hash: Fingerprint,
3637
}
3738

3839
// We don't store the list of impls in a flat list because each cached list of
@@ -94,7 +95,7 @@ impl<'a, 'gcx, 'tcx> TraitDef {
9495
unsafety: hir::Unsafety,
9596
paren_sugar: bool,
9697
has_default_impl: bool,
97-
def_path_hash: u64)
98+
def_path_hash: Fingerprint)
9899
-> TraitDef {
99100
TraitDef {
100101
def_id,

src/librustc_incremental/calculate_svh/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
224224
{
225225
let tcx = self.hcx.tcx();
226226

227-
let mut impls: Vec<(u64, Fingerprint)> = krate
227+
let mut impls: Vec<(Fingerprint, Fingerprint)> = krate
228228
.trait_impls
229229
.iter()
230230
.map(|(&trait_id, impls)| {

src/librustc_metadata/cstore_impl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
1717
ExternCrate, NativeLibrary, MetadataLoader, LinkMeta,
1818
LinkagePreference, LoadedMacro, EncodedMetadata};
1919
use rustc::hir::def;
20+
use rustc::ich;
2021
use rustc::middle::lang_items;
2122
use rustc::session::Session;
2223
use rustc::ty::{self, TyCtxt};
@@ -337,7 +338,7 @@ impl CrateStore for cstore::CStore {
337338
self.get_crate_data(def.krate).def_path(def.index)
338339
}
339340

340-
fn def_path_hash(&self, def: DefId) -> u64 {
341+
fn def_path_hash(&self, def: DefId) -> ich::Fingerprint {
341342
self.get_crate_data(def.krate).def_path_hash(def.index)
342343
}
343344

src/librustc_metadata/decoder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use schema::*;
1616
use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
1717
use rustc::hir::map::{DefKey, DefPath, DefPathData};
1818
use rustc::hir;
19+
use rustc::ich;
1920

2021
use rustc::middle::cstore::LinkagePreference;
2122
use rustc::hir::def::{self, Def, CtorKind};
@@ -1106,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata {
11061107
}
11071108

11081109
#[inline]
1109-
pub fn def_path_hash(&self, index: DefIndex) -> u64 {
1110+
pub fn def_path_hash(&self, index: DefIndex) -> ich::Fingerprint {
11101111
self.def_path_table.def_path_hash(index)
11111112
}
11121113

0 commit comments

Comments
 (0)