Auto merge of #119259 - cjgillot:single-crate-id, r=Mark-Simulacrum
Only store StableCrateId once in DefPathTable. https://github.com/rust-lang/rust/pull/119238 made me think of this. cc `@Mark-Simulacrum`
This commit is contained in:
commit
dc450f9dcb
4 changed files with 40 additions and 32 deletions
|
@ -25,7 +25,7 @@ impl Hash64 {
|
||||||
pub const ZERO: Hash64 = Hash64 { inner: 0 };
|
pub const ZERO: Hash64 = Hash64 { inner: 0 };
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn new(n: u64) -> Self {
|
pub fn new(n: u64) -> Self {
|
||||||
Self { inner: n }
|
Self { inner: n }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
use rustc_span::def_id::{DefIndex, DefPathHash};
|
use rustc_span::def_id::DefIndex;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Config;
|
pub struct Config;
|
||||||
|
|
||||||
impl odht::Config for Config {
|
impl odht::Config for Config {
|
||||||
type Key = DefPathHash;
|
// This hash-map is single-crate, so we only need to key by the local hash.
|
||||||
|
type Key = Hash64;
|
||||||
type Value = DefIndex;
|
type Value = DefIndex;
|
||||||
|
|
||||||
type EncodedKey = [u8; 16];
|
type EncodedKey = [u8; 8];
|
||||||
type EncodedValue = [u8; 4];
|
type EncodedValue = [u8; 4];
|
||||||
|
|
||||||
type H = odht::UnHashFn;
|
type H = odht::UnHashFn;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn encode_key(k: &DefPathHash) -> [u8; 16] {
|
fn encode_key(k: &Hash64) -> [u8; 8] {
|
||||||
k.0.to_le_bytes()
|
k.as_u64().to_le_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -24,8 +25,8 @@ impl odht::Config for Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn decode_key(k: &[u8; 16]) -> DefPathHash {
|
fn decode_key(k: &[u8; 8]) -> Hash64 {
|
||||||
DefPathHash(Fingerprint::from_le_bytes(*k))
|
Hash64::new(u64::from_le_bytes(*k))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -20,27 +20,42 @@ use std::hash::Hash;
|
||||||
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
|
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
|
||||||
/// stores the `DefIndex` of its parent.
|
/// stores the `DefIndex` of its parent.
|
||||||
/// There is one `DefPathTable` for each crate.
|
/// There is one `DefPathTable` for each crate.
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DefPathTable {
|
pub struct DefPathTable {
|
||||||
|
stable_crate_id: StableCrateId,
|
||||||
index_to_key: IndexVec<DefIndex, DefKey>,
|
index_to_key: IndexVec<DefIndex, DefKey>,
|
||||||
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
|
// We do only store the local hash, as all the definitions are from the current crate.
|
||||||
|
def_path_hashes: IndexVec<DefIndex, Hash64>,
|
||||||
def_path_hash_to_index: DefPathHashMap,
|
def_path_hash_to_index: DefPathHashMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefPathTable {
|
impl DefPathTable {
|
||||||
|
fn new(stable_crate_id: StableCrateId) -> DefPathTable {
|
||||||
|
DefPathTable {
|
||||||
|
stable_crate_id,
|
||||||
|
index_to_key: Default::default(),
|
||||||
|
def_path_hashes: Default::default(),
|
||||||
|
def_path_hash_to_index: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
|
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
|
||||||
|
// Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
|
||||||
|
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
|
||||||
|
let local_hash = def_path_hash.local_hash();
|
||||||
|
|
||||||
let index = {
|
let index = {
|
||||||
let index = DefIndex::from(self.index_to_key.len());
|
let index = DefIndex::from(self.index_to_key.len());
|
||||||
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
|
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
|
||||||
self.index_to_key.push(key);
|
self.index_to_key.push(key);
|
||||||
index
|
index
|
||||||
};
|
};
|
||||||
self.def_path_hashes.push(def_path_hash);
|
self.def_path_hashes.push(local_hash);
|
||||||
debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
|
debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
|
||||||
|
|
||||||
// Check for hash collisions of DefPathHashes. These should be
|
// Check for hash collisions of DefPathHashes. These should be
|
||||||
// exceedingly rare.
|
// exceedingly rare.
|
||||||
if let Some(existing) = self.def_path_hash_to_index.insert(&def_path_hash, &index) {
|
if let Some(existing) = self.def_path_hash_to_index.insert(&local_hash, &index) {
|
||||||
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx));
|
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx));
|
||||||
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx));
|
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx));
|
||||||
|
|
||||||
|
@ -58,13 +73,6 @@ impl DefPathTable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert that all DefPathHashes correctly contain the local crate's
|
|
||||||
// StableCrateId
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if let Some(root) = self.def_path_hashes.get(CRATE_DEF_INDEX) {
|
|
||||||
assert!(def_path_hash.stable_crate_id() == root.stable_crate_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,19 +81,19 @@ impl DefPathTable {
|
||||||
self.index_to_key[index]
|
self.index_to_key[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
|
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
|
||||||
let hash = self.def_path_hashes[index];
|
let hash = self.def_path_hashes[index];
|
||||||
debug!("def_path_hash({:?}) = {:?}", index, hash);
|
DefPathHash::new(self.stable_crate_id, hash)
|
||||||
hash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enumerated_keys_and_path_hashes(
|
pub fn enumerated_keys_and_path_hashes(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (DefIndex, &DefKey, &DefPathHash)> + ExactSizeIterator + '_ {
|
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator + '_ {
|
||||||
self.index_to_key
|
self.index_to_key
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
|
.map(move |(index, key)| (index, key, self.def_path_hash(index)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +104,6 @@ impl DefPathTable {
|
||||||
pub struct Definitions {
|
pub struct Definitions {
|
||||||
table: DefPathTable,
|
table: DefPathTable,
|
||||||
next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>,
|
next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>,
|
||||||
|
|
||||||
/// The [StableCrateId] of the local crate.
|
|
||||||
stable_crate_id: StableCrateId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A unique identifier that we can use to lookup a definition
|
/// A unique identifier that we can use to lookup a definition
|
||||||
|
@ -329,11 +334,11 @@ impl Definitions {
|
||||||
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.
|
||||||
let mut table = DefPathTable::default();
|
let mut table = DefPathTable::new(stable_crate_id);
|
||||||
let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
|
let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
|
||||||
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
|
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
|
||||||
|
|
||||||
Definitions { table, next_disambiguator: Default::default(), stable_crate_id }
|
Definitions { table, next_disambiguator: Default::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a definition with a parent definition.
|
/// Adds a definition with a parent definition.
|
||||||
|
@ -375,10 +380,10 @@ impl Definitions {
|
||||||
hash: DefPathHash,
|
hash: DefPathHash,
|
||||||
err: &mut dyn FnMut() -> !,
|
err: &mut dyn FnMut() -> !,
|
||||||
) -> LocalDefId {
|
) -> LocalDefId {
|
||||||
debug_assert!(hash.stable_crate_id() == self.stable_crate_id);
|
debug_assert!(hash.stable_crate_id() == self.table.stable_crate_id);
|
||||||
self.table
|
self.table
|
||||||
.def_path_hash_to_index
|
.def_path_hash_to_index
|
||||||
.get(&hash)
|
.get(&hash.local_hash())
|
||||||
.map(|local_def_index| LocalDefId { local_def_index })
|
.map(|local_def_index| LocalDefId { local_def_index })
|
||||||
.unwrap_or_else(|| err())
|
.unwrap_or_else(|| err())
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ impl DefPathHashMapRef<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
|
pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
|
||||||
match *self {
|
match *self {
|
||||||
DefPathHashMapRef::OwnedFromMetadata(ref map) => map.get(def_path_hash).unwrap(),
|
DefPathHashMapRef::OwnedFromMetadata(ref map) => {
|
||||||
|
map.get(&def_path_hash.local_hash()).unwrap()
|
||||||
|
}
|
||||||
DefPathHashMapRef::BorrowedFromTcx(_) => {
|
DefPathHashMapRef::BorrowedFromTcx(_) => {
|
||||||
panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization")
|
panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue