Auto merge of #110083 - saethlin:encode-hashes-as-bytes, r=cjgillot
Encode hashes as bytes, not varint In a few places, we store hashes as `u64` or `u128` and then apply `derive(Decodable, Encodable)` to the enclosing struct/enum. It is more efficient to encode hashes directly than try to apply some varint encoding. This PR adds two new types `Hash64` and `Hash128` which are produced by `StableHasher` and replace every use of storing a `u64` or `u128` that represents a hash. Distribution of the byte lengths of leb128 encodings, from `x build --stage 2` with `incremental = true` Before: ``` ( 1) 373418203 (53.7%, 53.7%): 1 ( 2) 196240113 (28.2%, 81.9%): 3 ( 3) 108157958 (15.6%, 97.5%): 2 ( 4) 17213120 ( 2.5%, 99.9%): 4 ( 5) 223614 ( 0.0%,100.0%): 9 ( 6) 216262 ( 0.0%,100.0%): 10 ( 7) 15447 ( 0.0%,100.0%): 5 ( 8) 3633 ( 0.0%,100.0%): 19 ( 9) 3030 ( 0.0%,100.0%): 8 ( 10) 1167 ( 0.0%,100.0%): 18 ( 11) 1032 ( 0.0%,100.0%): 7 ( 12) 1003 ( 0.0%,100.0%): 6 ( 13) 10 ( 0.0%,100.0%): 16 ( 14) 10 ( 0.0%,100.0%): 17 ( 15) 5 ( 0.0%,100.0%): 12 ( 16) 4 ( 0.0%,100.0%): 14 ``` After: ``` ( 1) 372939136 (53.7%, 53.7%): 1 ( 2) 196240140 (28.3%, 82.0%): 3 ( 3) 108014969 (15.6%, 97.5%): 2 ( 4) 17192375 ( 2.5%,100.0%): 4 ( 5) 435 ( 0.0%,100.0%): 5 ( 6) 83 ( 0.0%,100.0%): 18 ( 7) 79 ( 0.0%,100.0%): 10 ( 8) 50 ( 0.0%,100.0%): 9 ( 9) 6 ( 0.0%,100.0%): 19 ``` The remaining 9 or 10 and 18 or 19 are `u64` and `u128` respectively that have the high bits set. As far as I can tell these are coming primarily from `SwitchTargets`.
This commit is contained in:
commit
b3f1379509
38 changed files with 289 additions and 138 deletions
|
@ -79,7 +79,8 @@ pub trait LayoutCalculator {
|
||||||
{
|
{
|
||||||
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
|
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
|
||||||
// randomize field ordering with
|
// randomize field ordering with
|
||||||
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
|
let mut rng =
|
||||||
|
Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64());
|
||||||
|
|
||||||
// Shuffle the ordering of the fields
|
// Shuffle the ordering of the fields
|
||||||
optimizing.shuffle(&mut rng);
|
optimizing.shuffle(&mut rng);
|
||||||
|
|
|
@ -9,6 +9,7 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_data_structures::stable_hasher::StableOrd;
|
use rustc_data_structures::stable_hasher::StableOrd;
|
||||||
use rustc_index::vec::{IndexSlice, IndexVec};
|
use rustc_index::vec::{IndexSlice, IndexVec};
|
||||||
|
@ -77,12 +78,12 @@ pub struct ReprOptions {
|
||||||
pub flags: ReprFlags,
|
pub flags: ReprFlags,
|
||||||
/// The seed to be used for randomizing a type's layout
|
/// The seed to be used for randomizing a type's layout
|
||||||
///
|
///
|
||||||
/// Note: This could technically be a `[u8; 16]` (a `u128`) which would
|
/// Note: This could technically be a `Hash128` which would
|
||||||
/// be the "most accurate" hash as it'd encompass the item and crate
|
/// be the "most accurate" hash as it'd encompass the item and crate
|
||||||
/// hash without loss, but it does pay the price of being larger.
|
/// hash without loss, but it does pay the price of being larger.
|
||||||
/// Everything's a tradeoff, a `u64` seed should be sufficient for our
|
/// Everything's a tradeoff, a 64-bit seed should be sufficient for our
|
||||||
/// purposes (primarily `-Z randomize-layout`)
|
/// purposes (primarily `-Z randomize-layout`)
|
||||||
pub field_shuffle_seed: u64,
|
pub field_shuffle_seed: Hash64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReprOptions {
|
impl ReprOptions {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::value::Value;
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
|
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
|
||||||
|
@ -261,7 +261,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
|
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
alloc.hash_stable(&mut hcx, &mut hasher);
|
alloc.hash_stable(&mut hcx, &mut hasher);
|
||||||
hasher.finish::<u128>()
|
hasher.finish::<Hash128>()
|
||||||
});
|
});
|
||||||
llvm::set_value_name(value, format!("alloc_{hash:032x}").as_bytes());
|
llvm::set_value_name(value, format!("alloc_{hash:032x}").as_bytes());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ use rustc_codegen_ssa::debuginfo::type_names;
|
||||||
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
|
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_data_structures::stable_hasher::Hash128;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_hir::def_id::{DefId, DefIdMap};
|
use rustc_hir::def_id::{DefId, DefIdMap};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
@ -61,7 +62,7 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> {
|
||||||
llcontext: &'ll llvm::Context,
|
llcontext: &'ll llvm::Context,
|
||||||
llmod: &'ll llvm::Module,
|
llmod: &'ll llvm::Module,
|
||||||
builder: &'ll mut DIBuilder<'ll>,
|
builder: &'ll mut DIBuilder<'ll>,
|
||||||
created_files: RefCell<FxHashMap<Option<(u128, SourceFileHash)>, &'ll DIFile>>,
|
created_files: RefCell<FxHashMap<Option<(Hash128, SourceFileHash)>, &'ll DIFile>>,
|
||||||
|
|
||||||
type_map: metadata::TypeMap<'ll, 'tcx>,
|
type_map: metadata::TypeMap<'ll, 'tcx>,
|
||||||
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
|
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// * `"` is treated as the start of a string.
|
// * `"` is treated as the start of a string.
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
||||||
|
@ -675,8 +675,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||||
hcx.while_hashing_spans(false, |hcx| {
|
hcx.while_hashing_spans(false, |hcx| {
|
||||||
ct.to_valtree().hash_stable(hcx, &mut hasher)
|
ct.to_valtree().hash_stable(hcx, &mut hasher)
|
||||||
});
|
});
|
||||||
let hash: u64 = hasher.finish();
|
hasher.finish::<Hash64>()
|
||||||
hash
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if cpp_like_debuginfo(tcx) {
|
if cpp_like_debuginfo(tcx) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||||
}
|
}
|
||||||
sym::type_id => {
|
sym::type_id => {
|
||||||
ensure_monomorphic_enough(tcx, tp_ty)?;
|
ensure_monomorphic_enough(tcx, tp_ty)?;
|
||||||
ConstValue::from_u64(tcx.type_id_hash(tp_ty))
|
ConstValue::from_u64(tcx.type_id_hash(tp_ty).as_u64())
|
||||||
}
|
}
|
||||||
sym::variant_count => match tp_ty.kind() {
|
sym::variant_count => match tp_ty.kind() {
|
||||||
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
|
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::stable_hasher;
|
use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult};
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
@ -9,32 +9,49 @@ mod tests;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Fingerprint(u64, u64);
|
pub struct Fingerprint(u64, u64);
|
||||||
|
|
||||||
|
pub trait FingerprintComponent {
|
||||||
|
fn as_u64(&self) -> u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FingerprintComponent for Hash64 {
|
||||||
|
#[inline]
|
||||||
|
fn as_u64(&self) -> u64 {
|
||||||
|
Hash64::as_u64(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FingerprintComponent for u64 {
|
||||||
|
#[inline]
|
||||||
|
fn as_u64(&self) -> u64 {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Fingerprint {
|
impl Fingerprint {
|
||||||
pub const ZERO: Fingerprint = Fingerprint(0, 0);
|
pub const ZERO: Fingerprint = Fingerprint(0, 0);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(_0: u64, _1: u64) -> Fingerprint {
|
pub fn new<A, B>(_0: A, _1: B) -> Fingerprint
|
||||||
Fingerprint(_0, _1)
|
where
|
||||||
|
A: FingerprintComponent,
|
||||||
|
B: FingerprintComponent,
|
||||||
|
{
|
||||||
|
Fingerprint(_0.as_u64(), _1.as_u64())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
|
pub fn to_smaller_hash(&self) -> Hash64 {
|
||||||
Fingerprint(hash, hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_smaller_hash(&self) -> u64 {
|
|
||||||
// Even though both halves of the fingerprint are expected to be good
|
// Even though both halves of the fingerprint are expected to be good
|
||||||
// quality hash values, let's still combine the two values because the
|
// quality hash values, let's still combine the two values because the
|
||||||
// Fingerprints in DefPathHash have the StableCrateId portion which is
|
// Fingerprints in DefPathHash have the StableCrateId portion which is
|
||||||
// the same for all DefPathHashes from the same crate. Combining the
|
// the same for all DefPathHashes from the same crate. Combining the
|
||||||
// two halves makes sure we get a good quality hash in such cases too.
|
// two halves makes sure we get a good quality hash in such cases too.
|
||||||
self.0.wrapping_mul(3).wrapping_add(self.1)
|
Hash64::new(self.0.wrapping_mul(3).wrapping_add(self.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_value(&self) -> (u64, u64) {
|
pub fn split(&self) -> (Hash64, Hash64) {
|
||||||
(self.0, self.1)
|
(Hash64::new(self.0), Hash64::new(self.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -131,9 +148,9 @@ impl FingerprintHasher for crate::unhash::Unhasher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl stable_hasher::StableHasherResult for Fingerprint {
|
impl StableHasherResult for Fingerprint {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn finish(hasher: stable_hasher::StableHasher) -> Self {
|
fn finish(hasher: StableHasher) -> Self {
|
||||||
let (_0, _1) = hasher.finalize();
|
let (_0, _1) = hasher.finalize();
|
||||||
Fingerprint(_0, _1)
|
Fingerprint(_0, _1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::stable_hasher::Hash64;
|
||||||
|
|
||||||
// Check that `combine_commutative` is order independent.
|
// Check that `combine_commutative` is order independent.
|
||||||
#[test]
|
#[test]
|
||||||
fn combine_commutative_is_order_independent() {
|
fn combine_commutative_is_order_independent() {
|
||||||
let a = Fingerprint::new(0xf6622fb349898b06, 0x70be9377b2f9c610);
|
let a = Fingerprint::new(Hash64::new(0xf6622fb349898b06), Hash64::new(0x70be9377b2f9c610));
|
||||||
let b = Fingerprint::new(0xa9562bf5a2a5303c, 0x67d9b6c82034f13d);
|
let b = Fingerprint::new(Hash64::new(0xa9562bf5a2a5303c), Hash64::new(0x67d9b6c82034f13d));
|
||||||
let c = Fingerprint::new(0x0d013a27811dbbc3, 0x9a3f7b3d9142ec43);
|
let c = Fingerprint::new(Hash64::new(0x0d013a27811dbbc3), Hash64::new(0x9a3f7b3d9142ec43));
|
||||||
let permutations = [(a, b, c), (a, c, b), (b, a, c), (b, c, a), (c, a, b), (c, b, a)];
|
let permutations = [(a, b, c), (a, c, b), (b, a, c), (b, c, a), (c, a, b), (c, b, a)];
|
||||||
let f = a.combine_commutative(b).combine_commutative(c);
|
let f = a.combine_commutative(b).combine_commutative(c);
|
||||||
for p in &permutations {
|
for p in &permutations {
|
||||||
|
|
132
compiler/rustc_data_structures/src/hashes.rs
Normal file
132
compiler/rustc_data_structures/src/hashes.rs
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
//! rustc encodes a lot of hashes. If hashes are stored as `u64` or `u128`, a `derive(Encodable)`
|
||||||
|
//! will apply varint encoding to the hashes, which is less efficient than directly encoding the 8
|
||||||
|
//! or 16 bytes of the hash.
|
||||||
|
//!
|
||||||
|
//! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`.
|
||||||
|
//! `Hash64` and `Hash128` expose some utilty functions to encourage users to not extract the inner
|
||||||
|
//! hash value as an integer type and accidentally apply varint encoding to it.
|
||||||
|
//!
|
||||||
|
//! In contrast with `Fingerprint`, users of these types cannot and should not attempt to construct
|
||||||
|
//! and decompose these types into constitutent pieces. The point of these types is only to
|
||||||
|
//! connect the fact that they can only be produced by a `StableHasher` to their
|
||||||
|
//! `Encode`/`Decode` impls.
|
||||||
|
|
||||||
|
use crate::stable_hasher::{StableHasher, StableHasherResult};
|
||||||
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
|
use std::fmt;
|
||||||
|
use std::ops::BitXorAssign;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
|
||||||
|
pub struct Hash64 {
|
||||||
|
inner: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash64 {
|
||||||
|
pub const ZERO: Hash64 = Hash64 { inner: 0 };
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn new(n: u64) -> Self {
|
||||||
|
Self { inner: n }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_u64(self) -> u64 {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitXorAssign<u64> for Hash64 {
|
||||||
|
#[inline]
|
||||||
|
fn bitxor_assign(&mut self, rhs: u64) {
|
||||||
|
self.inner ^= rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: Encoder> Encodable<S> for Hash64 {
|
||||||
|
#[inline]
|
||||||
|
fn encode(&self, s: &mut S) {
|
||||||
|
s.emit_raw_bytes(&self.inner.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: Decoder> Decodable<D> for Hash64 {
|
||||||
|
#[inline]
|
||||||
|
fn decode(d: &mut D) -> Self {
|
||||||
|
Self { inner: u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StableHasherResult for Hash64 {
|
||||||
|
#[inline]
|
||||||
|
fn finish(hasher: StableHasher) -> Self {
|
||||||
|
Self { inner: hasher.finalize().0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Hash64 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.inner.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::LowerHex for Hash64 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::LowerHex::fmt(&self.inner, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
|
||||||
|
pub struct Hash128 {
|
||||||
|
inner: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash128 {
|
||||||
|
#[inline]
|
||||||
|
pub fn truncate(self) -> Hash64 {
|
||||||
|
Hash64 { inner: self.inner as u64 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn wrapping_add(self, other: Self) -> Self {
|
||||||
|
Self { inner: self.inner.wrapping_add(other.inner) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_u128(self) -> u128 {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: Encoder> Encodable<S> for Hash128 {
|
||||||
|
#[inline]
|
||||||
|
fn encode(&self, s: &mut S) {
|
||||||
|
s.emit_raw_bytes(&self.inner.to_le_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: Decoder> Decodable<D> for Hash128 {
|
||||||
|
#[inline]
|
||||||
|
fn decode(d: &mut D) -> Self {
|
||||||
|
Self { inner: u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StableHasherResult for Hash128 {
|
||||||
|
#[inline]
|
||||||
|
fn finish(hasher: StableHasher) -> Self {
|
||||||
|
let (_0, _1) = hasher.finalize();
|
||||||
|
Self { inner: u128::from(_0) | (u128::from(_1) << 64) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Hash128 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.inner.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::LowerHex for Hash128 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::LowerHex::fmt(&self.inner, f)
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,6 +86,7 @@ pub mod work_queue;
|
||||||
pub use atomic_ref::AtomicRef;
|
pub use atomic_ref::AtomicRef;
|
||||||
pub mod aligned;
|
pub mod aligned;
|
||||||
pub mod frozen;
|
pub mod frozen;
|
||||||
|
mod hashes;
|
||||||
pub mod owned_slice;
|
pub mod owned_slice;
|
||||||
pub mod sso;
|
pub mod sso;
|
||||||
pub mod steal;
|
pub mod steal;
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::sip128::SipHasher128;
|
||||||
use rustc_index::bit_set;
|
use rustc_index::bit_set;
|
||||||
use rustc_index::vec;
|
use rustc_index::vec;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use std::fmt;
|
||||||
use std::hash::{BuildHasher, Hash, Hasher};
|
use std::hash::{BuildHasher, Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -9,6 +10,8 @@ use std::mem;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
pub use crate::hashes::{Hash128, Hash64};
|
||||||
|
|
||||||
/// When hashing something that ends up affecting properties like symbol names,
|
/// When hashing something that ends up affecting properties like symbol names,
|
||||||
/// we want these symbol names to be calculated independently of other factors
|
/// we want these symbol names to be calculated independently of other factors
|
||||||
/// like what architecture you're compiling *from*.
|
/// like what architecture you're compiling *from*.
|
||||||
|
@ -20,8 +23,8 @@ pub struct StableHasher {
|
||||||
state: SipHasher128,
|
state: SipHasher128,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::fmt::Debug for StableHasher {
|
impl fmt::Debug for StableHasher {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{:?}", self.state)
|
write!(f, "{:?}", self.state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,21 +45,6 @@ impl StableHasher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StableHasherResult for u128 {
|
|
||||||
#[inline]
|
|
||||||
fn finish(hasher: StableHasher) -> Self {
|
|
||||||
let (_0, _1) = hasher.finalize();
|
|
||||||
u128::from(_0) | (u128::from(_1) << 64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StableHasherResult for u64 {
|
|
||||||
#[inline]
|
|
||||||
fn finish(hasher: StableHasher) -> Self {
|
|
||||||
hasher.finalize().0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StableHasher {
|
impl StableHasher {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finalize(self) -> (u64, u64) {
|
pub fn finalize(self) -> (u64, u64) {
|
||||||
|
@ -287,6 +275,9 @@ impl_stable_traits_for_trivial_type!(i128);
|
||||||
impl_stable_traits_for_trivial_type!(char);
|
impl_stable_traits_for_trivial_type!(char);
|
||||||
impl_stable_traits_for_trivial_type!(());
|
impl_stable_traits_for_trivial_type!(());
|
||||||
|
|
||||||
|
impl_stable_traits_for_trivial_type!(Hash64);
|
||||||
|
impl_stable_traits_for_trivial_type!(Hash128);
|
||||||
|
|
||||||
impl<CTX> HashStable<CTX> for ! {
|
impl<CTX> HashStable<CTX> for ! {
|
||||||
fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
|
fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
@ -669,7 +660,7 @@ fn stable_hash_reduce<HCX, I, C, F>(
|
||||||
.map(|value| {
|
.map(|value| {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
hash_function(&mut hasher, hcx, value);
|
hash_function(&mut hasher, hcx, value);
|
||||||
hasher.finish::<u128>()
|
hasher.finish::<Hash128>()
|
||||||
})
|
})
|
||||||
.reduce(|accum, value| accum.wrapping_add(value));
|
.reduce(|accum, value| accum.wrapping_add(value));
|
||||||
hash.hash_stable(hcx, hasher);
|
hash.hash_stable(hcx, hasher);
|
||||||
|
|
|
@ -72,7 +72,7 @@ fn test_hash_isize() {
|
||||||
assert_eq!(h.finalize(), expected);
|
assert_eq!(h.finalize(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash<T: HashStable<()>>(t: &T) -> u128 {
|
fn hash<T: HashStable<()>>(t: &T) -> Hash128 {
|
||||||
let mut h = StableHasher::new();
|
let mut h = StableHasher::new();
|
||||||
let ctx = &mut ();
|
let ctx = &mut ();
|
||||||
t.hash_stable(ctx, &mut h);
|
t.hash_stable(ctx, &mut h);
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Svh {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_u64(&self) -> u64 {
|
pub fn as_u64(&self) -> u64 {
|
||||||
self.hash.to_smaller_hash()
|
self.hash.to_smaller_hash().as_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
|
|
|
@ -31,7 +31,7 @@ use Level::*;
|
||||||
use emitter::{is_case_difference, Emitter, EmitterWriter};
|
use emitter::{is_case_difference, Emitter, EmitterWriter};
|
||||||
use registry::Registry;
|
use registry::Registry;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
|
||||||
use rustc_data_structures::sync::{self, Lock, Lrc};
|
use rustc_data_structures::sync::{self, Lock, Lrc};
|
||||||
use rustc_data_structures::AtomicRef;
|
use rustc_data_structures::AtomicRef;
|
||||||
pub use rustc_error_messages::{
|
pub use rustc_error_messages::{
|
||||||
|
@ -427,7 +427,7 @@ struct HandlerInner {
|
||||||
/// This set contains a hash of every diagnostic that has been emitted by
|
/// This set contains a hash of every diagnostic that has been emitted by
|
||||||
/// this handler. These hashes is used to avoid emitting the same error
|
/// this handler. These hashes is used to avoid emitting the same error
|
||||||
/// twice.
|
/// twice.
|
||||||
emitted_diagnostics: FxHashSet<u128>,
|
emitted_diagnostics: FxHashSet<Hash128>,
|
||||||
|
|
||||||
/// Stashed diagnostics emitted in one stage of the compiler that may be
|
/// Stashed diagnostics emitted in one stage of the compiler that may be
|
||||||
/// stolen by other stages (e.g. to improve them and add more information).
|
/// stolen by other stages (e.g. to improve them and add more information).
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_IND
|
||||||
use crate::def_path_hash_map::DefPathHashMap;
|
use crate::def_path_hash_map::DefPathHashMap;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
use rustc_data_structures::stable_hasher::{Hash64, StableHasher};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ impl DefKey {
|
||||||
|
|
||||||
disambiguator.hash(&mut hasher);
|
disambiguator.hash(&mut hasher);
|
||||||
|
|
||||||
let local_hash: u64 = hasher.finish();
|
let local_hash = hasher.finish();
|
||||||
|
|
||||||
// Construct the new DefPathHash, making sure that the `crate_id`
|
// Construct the new DefPathHash, making sure that the `crate_id`
|
||||||
// portion of the hash is properly copied from the parent. This way the
|
// portion of the hash is properly copied from the parent. This way the
|
||||||
|
@ -325,7 +325,7 @@ impl Definitions {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_hash = DefPathHash::new(stable_crate_id, 0);
|
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
|
||||||
let def_path_hash = key.compute_stable_hash(parent_hash);
|
let def_path_hash = key.compute_stable_hash(parent_hash);
|
||||||
|
|
||||||
// Create the root definition.
|
// Create the root definition.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData};
|
use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData};
|
||||||
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_span::def_id::{DefPathHash, StableCrateId};
|
use rustc_span::def_id::{DefPathHash, StableCrateId};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::{create_session_if_not_set_then, Symbol};
|
use rustc_span::{create_session_if_not_set_then, Symbol};
|
||||||
|
@ -24,7 +25,7 @@ fn def_path_hash_depends_on_crate_id() {
|
||||||
assert_ne!(h0.local_hash(), h1.local_hash());
|
assert_ne!(h0.local_hash(), h1.local_hash());
|
||||||
|
|
||||||
fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash {
|
fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash {
|
||||||
let parent_hash = DefPathHash::new(stable_crate_id, 0);
|
let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO);
|
||||||
|
|
||||||
let key = DefKey {
|
let key = DefKey {
|
||||||
parent: None,
|
parent: None,
|
||||||
|
|
|
@ -601,7 +601,7 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
|
||||||
fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf {
|
fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf {
|
||||||
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
|
let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
|
||||||
|
|
||||||
let stable_crate_id = base_n::encode(stable_crate_id.to_u64() as u128, INT_ENCODE_BASE);
|
let stable_crate_id = base_n::encode(stable_crate_id.as_u64() as u128, INT_ENCODE_BASE);
|
||||||
|
|
||||||
let crate_name = format!("{}-{}", crate_name, stable_crate_id);
|
let crate_name = format!("{}-{}", crate_name, stable_crate_id);
|
||||||
incr_dir.join(crate_name)
|
incr_dir.join(crate_name)
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_ast::Attribute;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||||
use rustc_data_structures::memmap::{Mmap, MmapMut};
|
use rustc_data_structures::memmap::{Mmap, MmapMut};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
|
use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -531,7 +531,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
adapted.name_hash = {
|
adapted.name_hash = {
|
||||||
let mut hasher: StableHasher = StableHasher::new();
|
let mut hasher: StableHasher = StableHasher::new();
|
||||||
adapted.name.hash(&mut hasher);
|
adapted.name.hash(&mut hasher);
|
||||||
hasher.finish::<u128>()
|
hasher.finish::<Hash128>()
|
||||||
};
|
};
|
||||||
Lrc::new(adapted)
|
Lrc::new(adapted)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -357,7 +357,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
|
||||||
Fingerprint::new(
|
Fingerprint::new(
|
||||||
// `owner` is local, so is completely defined by the local hash
|
// `owner` is local, so is completely defined by the local hash
|
||||||
def_path_hash.local_hash(),
|
def_path_hash.local_hash(),
|
||||||
local_id.as_u32().into(),
|
local_id.as_u32() as u64,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
|
||||||
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
|
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
|
||||||
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value();
|
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
|
||||||
let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
|
let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
|
||||||
let def_id = tcx
|
let def_id = tcx
|
||||||
.def_path_hash_to_def_id(def_path_hash, &mut || {
|
.def_path_hash_to_def_id(def_path_hash, &mut || {
|
||||||
|
@ -378,6 +378,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
|
||||||
})
|
})
|
||||||
.expect_local();
|
.expect_local();
|
||||||
let local_id = local_id
|
let local_id = local_id
|
||||||
|
.as_u64()
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
|
.unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
|
||||||
Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
|
Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
|
||||||
|
|
|
@ -72,6 +72,6 @@ pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
|
||||||
format!(
|
format!(
|
||||||
"rust_metadata_{}_{:08x}",
|
"rust_metadata_{}_{:08x}",
|
||||||
tcx.crate_name(LOCAL_CRATE),
|
tcx.crate_name(LOCAL_CRATE),
|
||||||
tcx.sess.local_stable_crate_id().to_u64(),
|
tcx.sess.local_stable_crate_id(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rustc_attr::InlineAttr;
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
use rustc_hir::ItemId;
|
use rustc_hir::ItemId;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
@ -313,8 +313,8 @@ impl<'tcx> CodegenUnit<'tcx> {
|
||||||
// avoid collisions and is still reasonably short for filenames.
|
// avoid collisions and is still reasonably short for filenames.
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
human_readable_name.hash(&mut hasher);
|
human_readable_name.hash(&mut hasher);
|
||||||
let hash: u128 = hasher.finish();
|
let hash: Hash128 = hasher.finish();
|
||||||
let hash = hash & ((1u128 << 80) - 1);
|
let hash = hash.as_u128() & ((1u128 << 80) - 1);
|
||||||
base_n::encode(hash, base_n::CASE_INSENSITIVE)
|
base_n::encode(hash, base_n::CASE_INSENSITIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,22 +505,13 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
|
||||||
// instantiating stuff for upstream crates.
|
// instantiating stuff for upstream crates.
|
||||||
let local_crate_id = if cnum != LOCAL_CRATE {
|
let local_crate_id = if cnum != LOCAL_CRATE {
|
||||||
let local_stable_crate_id = tcx.sess.local_stable_crate_id();
|
let local_stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||||
format!(
|
format!("-in-{}.{:08x}", tcx.crate_name(LOCAL_CRATE), local_stable_crate_id)
|
||||||
"-in-{}.{:08x}",
|
|
||||||
tcx.crate_name(LOCAL_CRATE),
|
|
||||||
local_stable_crate_id.to_u64() as u32,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let stable_crate_id = tcx.sess.local_stable_crate_id();
|
let stable_crate_id = tcx.sess.local_stable_crate_id();
|
||||||
format!(
|
format!("{}.{:08x}{}", tcx.crate_name(cnum), stable_crate_id, local_crate_id)
|
||||||
"{}.{:08x}{}",
|
|
||||||
tcx.crate_name(cnum),
|
|
||||||
stable_crate_id.to_u64() as u32,
|
|
||||||
local_crate_id,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
write!(cgu_name, "{}", crate_prefix).unwrap();
|
write!(cgu_name, "{}", crate_prefix).unwrap();
|
||||||
|
|
|
@ -141,14 +141,18 @@ impl<CTX> crate::ty::HashStable<CTX> for ScalarInt {
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for ScalarInt {
|
impl<S: Encoder> Encodable<S> for ScalarInt {
|
||||||
fn encode(&self, s: &mut S) {
|
fn encode(&self, s: &mut S) {
|
||||||
s.emit_u128(self.data);
|
let size = self.size.get();
|
||||||
s.emit_u8(self.size.get());
|
s.emit_u8(size);
|
||||||
|
s.emit_raw_bytes(&self.data.to_le_bytes()[..size as usize]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Decoder> Decodable<D> for ScalarInt {
|
impl<D: Decoder> Decodable<D> for ScalarInt {
|
||||||
fn decode(d: &mut D) -> ScalarInt {
|
fn decode(d: &mut D) -> ScalarInt {
|
||||||
ScalarInt { data: d.read_u128(), size: NonZeroU8::new(d.read_u8()).unwrap() }
|
let mut data = [0u8; 16];
|
||||||
|
let size = d.read_u8();
|
||||||
|
data[..size as usize].copy_from_slice(d.read_raw_bytes(size as usize));
|
||||||
|
ScalarInt { data: u128::from_le_bytes(data), size: NonZeroU8::new(size).unwrap() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -925,7 +925,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
crate_name,
|
crate_name,
|
||||||
// Don't print the whole stable crate id. That's just
|
// Don't print the whole stable crate id. That's just
|
||||||
// annoying in debug output.
|
// annoying in debug output.
|
||||||
stable_crate_id.to_u64() >> (8 * 6),
|
stable_crate_id.as_u64() >> (8 * 6),
|
||||||
self.def_path(def_id).to_string_no_crate_verbose()
|
self.def_path(def_id).to_string_no_crate_verbose()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::ty::{
|
||||||
use crate::ty::{GenericArgKind, SubstsRef};
|
use crate::ty::{GenericArgKind, SubstsRef};
|
||||||
use rustc_apfloat::Float as _;
|
use rustc_apfloat::Float as _;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||||
|
@ -124,7 +124,7 @@ impl IntTypeExt for IntegerType {
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Creates a hash of the type `Ty` which will be the same no matter what crate
|
/// Creates a hash of the type `Ty` which will be the same no matter what crate
|
||||||
/// context it's calculated within. This is used by the `type_id` intrinsic.
|
/// context it's calculated within. This is used by the `type_id` intrinsic.
|
||||||
pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
|
pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash64 {
|
||||||
// We want the type_id be independent of the types free regions, so we
|
// We want the type_id be independent of the types free regions, so we
|
||||||
// erase them. The erase_regions() call will also anonymize bound
|
// erase them. The erase_regions() call will also anonymize bound
|
||||||
// regions, which is desirable too.
|
// regions, which is desirable too.
|
||||||
|
|
|
@ -577,5 +577,10 @@ fn get_body_span<'tcx>(
|
||||||
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {
|
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {
|
||||||
// FIXME(cjgillot) Stop hashing HIR manually here.
|
// FIXME(cjgillot) Stop hashing HIR manually here.
|
||||||
let owner = hir_body.id().hir_id.owner;
|
let owner = hir_body.id().hir_id.owner;
|
||||||
tcx.hir_owner_nodes(owner).unwrap().opt_hash_including_bodies.unwrap().to_smaller_hash()
|
tcx.hir_owner_nodes(owner)
|
||||||
|
.unwrap()
|
||||||
|
.opt_hash_including_bodies
|
||||||
|
.unwrap()
|
||||||
|
.to_smaller_hash()
|
||||||
|
.as_u64()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::QueryCtxt;
|
use crate::QueryCtxt;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||||
use rustc_data_structures::memmap::Mmap;
|
use rustc_data_structures::memmap::Mmap;
|
||||||
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
|
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
|
||||||
use rustc_data_structures::unhash::UnhashMap;
|
use rustc_data_structures::unhash::UnhashMap;
|
||||||
use rustc_data_structures::unord::UnordSet;
|
use rustc_data_structures::unord::UnordSet;
|
||||||
|
@ -138,7 +139,7 @@ impl AbsoluteBytePos {
|
||||||
/// is the only thing available when decoding the cache's [Footer].
|
/// is the only thing available when decoding the cache's [Footer].
|
||||||
#[derive(Encodable, Decodable, Clone, Debug)]
|
#[derive(Encodable, Decodable, Clone, Debug)]
|
||||||
struct EncodedSourceFileId {
|
struct EncodedSourceFileId {
|
||||||
file_name_hash: u64,
|
file_name_hash: Hash64,
|
||||||
stable_crate_id: StableCrateId,
|
stable_crate_id: StableCrateId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +668,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
let local_hash: u64 = decoder.tcx.with_stable_hashing_context(|mut hcx| {
|
let local_hash = decoder.tcx.with_stable_hashing_context(|mut hcx| {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
|
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
|
||||||
hasher.finish()
|
hasher.finish()
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
|
use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
|
||||||
use crate::profiling_support::QueryKeyStringCache;
|
use crate::profiling_support::QueryKeyStringCache;
|
||||||
use crate::{on_disk_cache, Queries};
|
use crate::{on_disk_cache, Queries};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{AtomicU64, Lock};
|
use rustc_data_structures::sync::{AtomicU64, Lock};
|
||||||
use rustc_errors::{Diagnostic, Handler};
|
use rustc_errors::{Diagnostic, Handler};
|
||||||
use rustc_middle::dep_graph::{
|
use rustc_middle::dep_graph::{
|
||||||
|
@ -342,7 +342,7 @@ pub(crate) fn create_query_frame<
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
|
std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
|
||||||
key.hash_stable(&mut hcx, &mut hasher);
|
key.hash_stable(&mut hcx, &mut hasher);
|
||||||
hasher.finish::<u64>()
|
hasher.finish::<Hash64>()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let ty_adt_id = key.ty_adt_id();
|
let ty_adt_id = key.ty_adt_id();
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub use self::config::{HashResult, QueryConfig, TryLoadFromDisk};
|
||||||
|
|
||||||
use crate::dep_graph::DepKind;
|
use crate::dep_graph::DepKind;
|
||||||
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
|
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
|
||||||
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_data_structures::sync::Lock;
|
use rustc_data_structures::sync::Lock;
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
|
@ -37,7 +38,7 @@ pub struct QueryStackFrame<D: DepKind> {
|
||||||
/// This hash is used to deterministically pick
|
/// This hash is used to deterministically pick
|
||||||
/// a query to remove cycles in the parallel compiler.
|
/// a query to remove cycles in the parallel compiler.
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
hash: u64,
|
hash: Hash64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DepKind> QueryStackFrame<D> {
|
impl<D: DepKind> QueryStackFrame<D> {
|
||||||
|
@ -49,7 +50,7 @@ impl<D: DepKind> QueryStackFrame<D> {
|
||||||
def_kind: Option<DefKind>,
|
def_kind: Option<DefKind>,
|
||||||
dep_kind: D,
|
dep_kind: D,
|
||||||
ty_adt_id: Option<DefId>,
|
ty_adt_id: Option<DefId>,
|
||||||
_hash: impl FnOnce() -> u64,
|
_hash: impl FnOnce() -> Hash64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
description,
|
description,
|
||||||
|
|
|
@ -573,7 +573,7 @@ where
|
||||||
// from disk. Re-hashing results is fairly expensive, so we can't
|
// from disk. Re-hashing results is fairly expensive, so we can't
|
||||||
// currently afford to verify every hash. This subset should still
|
// currently afford to verify every hash. This subset should still
|
||||||
// give us some coverage of potential bugs though.
|
// give us some coverage of potential bugs though.
|
||||||
let try_verify = prev_fingerprint.as_value().1 % 32 == 0;
|
let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0;
|
||||||
if std::intrinsics::unlikely(
|
if std::intrinsics::unlikely(
|
||||||
try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
|
try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -811,7 +811,7 @@ impl Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
|
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
|
||||||
format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.to_u64())
|
format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.as_u64())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
|
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use crate::{HashStableContext, Symbol};
|
use crate::{HashStableContext, Symbol};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey};
|
||||||
use rustc_data_structures::unhash::Unhasher;
|
use rustc_data_structures::unhash::Unhasher;
|
||||||
use rustc_data_structures::AtomicRef;
|
use rustc_data_structures::AtomicRef;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_macros::HashStable_Generic;
|
use rustc_macros::HashStable_Generic;
|
||||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{BuildHasherDefault, Hash, Hasher};
|
use std::hash::{BuildHasherDefault, Hash, Hasher};
|
||||||
|
|
||||||
|
@ -105,20 +104,20 @@ impl DefPathHash {
|
||||||
/// originates from.
|
/// originates from.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn stable_crate_id(&self) -> StableCrateId {
|
pub fn stable_crate_id(&self) -> StableCrateId {
|
||||||
StableCrateId(self.0.as_value().0)
|
StableCrateId(self.0.split().0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the crate-local part of the [DefPathHash].
|
/// Returns the crate-local part of the [DefPathHash].
|
||||||
///
|
///
|
||||||
/// Used for tests.
|
/// Used for tests.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_hash(&self) -> u64 {
|
pub fn local_hash(&self) -> Hash64 {
|
||||||
self.0.as_value().1
|
self.0.split().1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a new [DefPathHash] with the given [StableCrateId] and
|
/// Builds a new [DefPathHash] with the given [StableCrateId] and
|
||||||
/// `local_hash`, where `local_hash` must be unique within its crate.
|
/// `local_hash`, where `local_hash` must be unique within its crate.
|
||||||
pub fn new(stable_crate_id: StableCrateId, local_hash: u64) -> DefPathHash {
|
pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
|
||||||
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,13 +128,6 @@ impl Default for DefPathHash {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<Fingerprint> for DefPathHash {
|
|
||||||
#[inline]
|
|
||||||
fn borrow(&self) -> &Fingerprint {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
|
/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
|
||||||
/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
|
/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
|
||||||
/// [`DefId`]. It is stable across compilation sessions.
|
/// [`DefId`]. It is stable across compilation sessions.
|
||||||
|
@ -147,15 +139,11 @@ impl Borrow<Fingerprint> for DefPathHash {
|
||||||
///
|
///
|
||||||
/// For more information on the possibility of hash collisions in rustc,
|
/// For more information on the possibility of hash collisions in rustc,
|
||||||
/// see the discussion in [`DefId`].
|
/// see the discussion in [`DefId`].
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
#[derive(Hash, HashStable_Generic, Encodable, Decodable)]
|
||||||
pub struct StableCrateId(pub(crate) u64);
|
pub struct StableCrateId(pub(crate) Hash64);
|
||||||
|
|
||||||
impl StableCrateId {
|
impl StableCrateId {
|
||||||
pub fn to_u64(self) -> u64 {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the stable ID for a crate with the given name and
|
/// Computes the stable ID for a crate with the given name and
|
||||||
/// `-Cmetadata` arguments.
|
/// `-Cmetadata` arguments.
|
||||||
pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId {
|
pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId {
|
||||||
|
@ -197,6 +185,17 @@ impl StableCrateId {
|
||||||
|
|
||||||
StableCrateId(hasher.finish())
|
StableCrateId(hasher.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_u64(self) -> u64 {
|
||||||
|
self.0.as_u64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::LowerHex for StableCrateId {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::LowerHex::fmt(&self.0, f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
|
|
|
@ -33,7 +33,7 @@ use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::stable_hasher::HashingControls;
|
use rustc_data_structures::stable_hasher::HashingControls;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{Lock, Lrc};
|
use rustc_data_structures::sync::{Lock, Lrc};
|
||||||
use rustc_data_structures::unhash::UnhashMap;
|
use rustc_data_structures::unhash::UnhashMap;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
|
@ -123,15 +123,15 @@ impl ExpnHash {
|
||||||
/// originates from.
|
/// originates from.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn stable_crate_id(self) -> StableCrateId {
|
pub fn stable_crate_id(self) -> StableCrateId {
|
||||||
StableCrateId(self.0.as_value().0)
|
StableCrateId(self.0.split().0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the crate-local part of the [ExpnHash].
|
/// Returns the crate-local part of the [ExpnHash].
|
||||||
///
|
///
|
||||||
/// Used for tests.
|
/// Used for tests.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_hash(self) -> u64 {
|
pub fn local_hash(self) -> Hash64 {
|
||||||
self.0.as_value().1
|
self.0.split().1
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -141,7 +141,7 @@ impl ExpnHash {
|
||||||
|
|
||||||
/// Builds a new [ExpnHash] with the given [StableCrateId] and
|
/// Builds a new [ExpnHash] with the given [StableCrateId] and
|
||||||
/// `local_hash`, where `local_hash` must be unique within its crate.
|
/// `local_hash`, where `local_hash` must be unique within its crate.
|
||||||
fn new(stable_crate_id: StableCrateId, local_hash: u64) -> ExpnHash {
|
fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> ExpnHash {
|
||||||
ExpnHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
ExpnHash(Fingerprint::new(stable_crate_id.0, local_hash))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ pub struct HygieneData {
|
||||||
/// would have collisions without a disambiguator.
|
/// would have collisions without a disambiguator.
|
||||||
/// The keys of this map are always computed with `ExpnData.disambiguator`
|
/// The keys of this map are always computed with `ExpnData.disambiguator`
|
||||||
/// set to 0.
|
/// set to 0.
|
||||||
expn_data_disambiguators: FxHashMap<u64, u32>,
|
expn_data_disambiguators: FxHashMap<Hash64, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HygieneData {
|
impl HygieneData {
|
||||||
|
@ -1040,7 +1040,7 @@ impl ExpnData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_expn(&self, ctx: &mut impl HashStableContext) -> u64 {
|
fn hash_expn(&self, ctx: &mut impl HashStableContext) -> Hash64 {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
self.hash_stable(ctx, &mut hasher);
|
self.hash_stable(ctx, &mut hasher);
|
||||||
hasher.finish()
|
hasher.finish()
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub mod fatal_error;
|
||||||
|
|
||||||
pub mod profiling;
|
pub mod profiling;
|
||||||
|
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{Lock, Lrc};
|
use rustc_data_structures::sync::{Lock, Lrc};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -282,22 +282,22 @@ impl RealFileName {
|
||||||
pub enum FileName {
|
pub enum FileName {
|
||||||
Real(RealFileName),
|
Real(RealFileName),
|
||||||
/// Call to `quote!`.
|
/// Call to `quote!`.
|
||||||
QuoteExpansion(u64),
|
QuoteExpansion(Hash64),
|
||||||
/// Command line.
|
/// Command line.
|
||||||
Anon(u64),
|
Anon(Hash64),
|
||||||
/// Hack in `src/librustc_ast/parse.rs`.
|
/// Hack in `src/librustc_ast/parse.rs`.
|
||||||
// FIXME(jseyfried)
|
// FIXME(jseyfried)
|
||||||
MacroExpansion(u64),
|
MacroExpansion(Hash64),
|
||||||
ProcMacroSourceCode(u64),
|
ProcMacroSourceCode(Hash64),
|
||||||
/// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`.
|
/// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`.
|
||||||
CfgSpec(u64),
|
CfgSpec(Hash64),
|
||||||
/// Strings provided as crate attributes in the CLI.
|
/// Strings provided as crate attributes in the CLI.
|
||||||
CliCrateAttr(u64),
|
CliCrateAttr(Hash64),
|
||||||
/// Custom sources for explicit parser calls from plugins and drivers.
|
/// Custom sources for explicit parser calls from plugins and drivers.
|
||||||
Custom(String),
|
Custom(String),
|
||||||
DocTest(PathBuf, isize),
|
DocTest(PathBuf, isize),
|
||||||
/// Post-substitution inline assembly from LLVM.
|
/// Post-substitution inline assembly from LLVM.
|
||||||
InlineAsm(u64),
|
InlineAsm(Hash64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PathBuf> for FileName {
|
impl From<PathBuf> for FileName {
|
||||||
|
@ -1343,7 +1343,7 @@ pub struct SourceFile {
|
||||||
/// Locations of characters removed during normalization.
|
/// Locations of characters removed during normalization.
|
||||||
pub normalized_pos: Vec<NormalizedPos>,
|
pub normalized_pos: Vec<NormalizedPos>,
|
||||||
/// A hash of the filename, used for speeding up hashing in incremental compilation.
|
/// A hash of the filename, used for speeding up hashing in incremental compilation.
|
||||||
pub name_hash: u128,
|
pub name_hash: Hash128,
|
||||||
/// Indicates which crate this `SourceFile` was imported from.
|
/// Indicates which crate this `SourceFile` was imported from.
|
||||||
pub cnum: CrateNum,
|
pub cnum: CrateNum,
|
||||||
}
|
}
|
||||||
|
@ -1472,7 +1472,7 @@ impl<D: Decoder> Decodable<D> for SourceFile {
|
||||||
};
|
};
|
||||||
let multibyte_chars: Vec<MultiByteChar> = Decodable::decode(d);
|
let multibyte_chars: Vec<MultiByteChar> = Decodable::decode(d);
|
||||||
let non_narrow_chars: Vec<NonNarrowChar> = Decodable::decode(d);
|
let non_narrow_chars: Vec<NonNarrowChar> = Decodable::decode(d);
|
||||||
let name_hash: u128 = Decodable::decode(d);
|
let name_hash = Decodable::decode(d);
|
||||||
let normalized_pos: Vec<NormalizedPos> = Decodable::decode(d);
|
let normalized_pos: Vec<NormalizedPos> = Decodable::decode(d);
|
||||||
let cnum: CrateNum = Decodable::decode(d);
|
let cnum: CrateNum = Decodable::decode(d);
|
||||||
SourceFile {
|
SourceFile {
|
||||||
|
@ -1514,7 +1514,7 @@ impl SourceFile {
|
||||||
let name_hash = {
|
let name_hash = {
|
||||||
let mut hasher: StableHasher = StableHasher::new();
|
let mut hasher: StableHasher = StableHasher::new();
|
||||||
name.hash(&mut hasher);
|
name.hash(&mut hasher);
|
||||||
hasher.finish::<u128>()
|
hasher.finish()
|
||||||
};
|
};
|
||||||
let end_pos = start_pos.to_usize() + src.len();
|
let end_pos = start_pos.to_usize() + src.len();
|
||||||
assert!(end_pos <= u32::MAX as usize);
|
assert!(end_pos <= u32::MAX as usize);
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub use crate::hygiene::{ExpnData, ExpnKind};
|
||||||
pub use crate::*;
|
pub use crate::*;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher};
|
||||||
use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
|
use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
@ -138,7 +138,7 @@ impl FileLoader for RealFileLoader {
|
||||||
pub struct StableSourceFileId {
|
pub struct StableSourceFileId {
|
||||||
/// A hash of the source file's [`FileName`]. This is hash so that it's size
|
/// A hash of the source file's [`FileName`]. This is hash so that it's size
|
||||||
/// is more predictable than if we included the actual [`FileName`] value.
|
/// is more predictable than if we included the actual [`FileName`] value.
|
||||||
pub file_name_hash: u64,
|
pub file_name_hash: Hash64,
|
||||||
|
|
||||||
/// The [`CrateNum`] of the crate this source file was originally parsed for.
|
/// The [`CrateNum`] of the crate this source file was originally parsed for.
|
||||||
/// We cannot include this information in the hash because at the time
|
/// We cannot include this information in the hash because at the time
|
||||||
|
@ -331,7 +331,7 @@ impl SourceMap {
|
||||||
&self,
|
&self,
|
||||||
filename: FileName,
|
filename: FileName,
|
||||||
src_hash: SourceFileHash,
|
src_hash: SourceFileHash,
|
||||||
name_hash: u128,
|
name_hash: Hash128,
|
||||||
source_len: usize,
|
source_len: usize,
|
||||||
cnum: CrateNum,
|
cnum: CrateNum,
|
||||||
file_local_lines: Lock<SourceFileLines>,
|
file_local_lines: Lock<SourceFileLines>,
|
||||||
|
|
|
@ -3,8 +3,12 @@ use super::*;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lookup_line() {
|
fn test_lookup_line() {
|
||||||
let source = "abcdefghijklm\nabcdefghij\n...".to_owned();
|
let source = "abcdefghijklm\nabcdefghij\n...".to_owned();
|
||||||
let sf =
|
let sf = SourceFile::new(
|
||||||
SourceFile::new(FileName::Anon(0), source, BytePos(3), SourceFileHashAlgorithm::Sha256);
|
FileName::Anon(Hash64::ZERO),
|
||||||
|
source,
|
||||||
|
BytePos(3),
|
||||||
|
SourceFileHashAlgorithm::Sha256,
|
||||||
|
);
|
||||||
sf.lines(|lines| assert_eq!(lines, &[BytePos(3), BytePos(17), BytePos(28)]));
|
sf.lines(|lines| assert_eq!(lines, &[BytePos(3), BytePos(17), BytePos(28)]));
|
||||||
|
|
||||||
assert_eq!(sf.lookup_line(BytePos(0)), None);
|
assert_eq!(sf.lookup_line(BytePos(0)), None);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::CrateNum;
|
use rustc_hir::def_id::CrateNum;
|
||||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||||
use rustc_middle::ty::print::{PrettyPrinter, Print, Printer};
|
use rustc_middle::ty::print::{PrettyPrinter, Print, Printer};
|
||||||
|
@ -93,7 +93,7 @@ fn get_symbol_hash<'tcx>(
|
||||||
item_type: Ty<'tcx>,
|
item_type: Ty<'tcx>,
|
||||||
|
|
||||||
instantiating_crate: Option<CrateNum>,
|
instantiating_crate: Option<CrateNum>,
|
||||||
) -> u64 {
|
) -> Hash64 {
|
||||||
let def_id = instance.def_id();
|
let def_id = instance.def_id();
|
||||||
let substs = instance.substs;
|
let substs = instance.substs;
|
||||||
debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
|
debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
|
||||||
|
@ -138,7 +138,7 @@ fn get_symbol_hash<'tcx>(
|
||||||
});
|
});
|
||||||
|
|
||||||
// 64 bits should be enough to avoid collisions.
|
// 64 bits should be enough to avoid collisions.
|
||||||
hasher.finish::<u64>()
|
hasher.finish::<Hash64>()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ impl SymbolPath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(mut self, hash: u64) -> String {
|
fn finish(mut self, hash: Hash64) -> String {
|
||||||
self.finalize_pending_component();
|
self.finalize_pending_component();
|
||||||
// E = end name-sequence
|
// E = end name-sequence
|
||||||
let _ = write!(self.result, "17h{hash:016x}E");
|
let _ = write!(self.result, "17h{hash:016x}E");
|
||||||
|
|
|
@ -406,7 +406,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
|
||||||
|
|
||||||
// Crate disambiguator and name
|
// Crate disambiguator and name
|
||||||
s.push('C');
|
s.push('C');
|
||||||
s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).to_u64()));
|
s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).as_u64()));
|
||||||
let crate_name = tcx.crate_name(def_path.krate).to_string();
|
let crate_name = tcx.crate_name(def_path.krate).to_string();
|
||||||
let _ = write!(s, "{}{}", crate_name.len(), &crate_name);
|
let _ = write!(s, "{}{}", crate_name.len(), &crate_name);
|
||||||
|
|
||||||
|
|
|
@ -731,7 +731,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
|
||||||
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
|
fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
|
||||||
self.push("C");
|
self.push("C");
|
||||||
let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
|
let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
|
||||||
self.push_disambiguator(stable_crate_id.to_u64());
|
self.push_disambiguator(stable_crate_id.as_u64());
|
||||||
let name = self.tcx.crate_name(cnum);
|
let name = self.tcx.crate_name(cnum);
|
||||||
self.push_ident(name.as_str());
|
self.push_ident(name.as_str());
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue