Skip to content

Commit 447f1f3

Browse files
Avoid sorting the item_ids array the StableHash impl of hir::Mod.
1 parent 79d8d08 commit 447f1f3

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

src/librustc/hir/map/definitions.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_data_structures::indexed_vec::{IndexVec};
2323
use rustc_data_structures::stable_hasher::StableHasher;
2424
use serialize::{Encodable, Decodable, Encoder, Decoder};
2525
use session::CrateDisambiguator;
26+
use std::borrow::Borrow;
2627
use std::fmt::Write;
2728
use std::hash::Hash;
2829
use syntax::ast;
@@ -389,6 +390,13 @@ pub struct DefPathHash(pub Fingerprint);
389390

390391
impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint });
391392

393+
impl Borrow<Fingerprint> for DefPathHash {
394+
#[inline]
395+
fn borrow(&self) -> &Fingerprint {
396+
&self.0
397+
}
398+
}
399+
392400
impl Definitions {
393401
/// Create new empty definition map.
394402
pub fn new() -> Definitions {

src/librustc/ich/fingerprint.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ impl Fingerprint {
4545
)
4646
}
4747

48+
// Combines two hashes in an order independent way. Make sure this is what
49+
// you want.
50+
#[inline]
51+
pub fn combine_commutative(self, other: Fingerprint) -> Fingerprint {
52+
let a = (self.1 as u128) << 64 | self.0 as u128;
53+
let b = (other.1 as u128) << 64 | other.0 as u128;
54+
55+
let c = a.wrapping_add(b);
56+
57+
Fingerprint((c >> 64) as u64, c as u64)
58+
}
59+
4860
pub fn to_hex(&self) -> String {
4961
format!("{:x}{:x}", self.0, self.1)
5062
}

src/librustc/ich/impls_hir.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use hir;
1515
use hir::map::DefPathHash;
1616
use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
17-
use ich::{StableHashingContext, NodeIdHashingMode};
17+
use ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
1818
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
1919
StableHasher, StableHasherResult};
2020
use std::mem;
@@ -767,15 +767,21 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
767767

768768
inner_span.hash_stable(hcx, hasher);
769769

770-
let mut item_ids: Vec<DefPathHash> = item_ids.iter().map(|id| {
771-
let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
772-
debug_assert_eq!(local_id, hir::ItemLocalId(0));
773-
def_path_hash
774-
}).collect();
775-
776-
item_ids.sort_unstable();
777-
778-
item_ids.hash_stable(hcx, hasher);
770+
// Combining the DefPathHashes directly is faster than feeding them
771+
// into the hasher. Because we use a commutative combine, we also don't
772+
// have to sort the array.
773+
let item_ids_hash = item_ids
774+
.iter()
775+
.map(|id| {
776+
let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
777+
debug_assert_eq!(local_id, hir::ItemLocalId(0));
778+
def_path_hash.0
779+
}).fold(Fingerprint::ZERO, |a, b| {
780+
a.combine_commutative(b)
781+
});
782+
783+
item_ids.len().hash_stable(hcx, hasher);
784+
item_ids_hash.hash_stable(hcx, hasher);
779785
}
780786
}
781787

0 commit comments

Comments
 (0)