Skip to content

Commit

Permalink
Specialize DefPathHash table to skip crate IDs
Browse files Browse the repository at this point in the history
The current implementation is ad-hoc and likely should be replaced with
a non-table based approach (i.e., fully pulling out DefPathHash from the
rmeta table infrastructure, of which we use ~none now), but this was an
easy way to get an initial PR out.

The main pending question is whether the assumption made here that there
is exactly one shared prefix accurate? If not, is it right that the
number should be typically small? (If so a deduplication scheme of which
this is a special case almost certainly makes sense).
  • Loading branch information
Mark-Simulacrum committed Dec 23, 2023
1 parent 5151b8c commit 5b3116c
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions compiler/rustc_metadata/src/rmeta/table.rs
Expand Up @@ -69,6 +69,11 @@ pub(super) trait FixedSizeEncoding: IsDefault {
/// Cannot use an associated `const BYTE_LEN: usize` instead due to const eval limitations.
type ByteArray;

const IS_DEF_PATH_HASH: bool = false;
fn from_16_bytes(_: &[u8; 16]) -> Self {
unreachable!()
}

fn from_bytes(b: &Self::ByteArray) -> Self;
fn write_to_bytes(self, b: &mut Self::ByteArray);
}
Expand Down Expand Up @@ -223,6 +228,11 @@ fixed_size_enum! {
impl FixedSizeEncoding for DefPathHash {
type ByteArray = [u8; 16];

const IS_DEF_PATH_HASH: bool = true;
fn from_16_bytes(b: &[u8; 16]) -> Self {
DefPathHash(Fingerprint::from_le_bytes(*b))
}

#[inline]
fn from_bytes(b: &[u8; 16]) -> Self {
DefPathHash(Fingerprint::from_le_bytes(*b))
Expand Down Expand Up @@ -482,6 +492,37 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui
pub(crate) fn encode(&self, buf: &mut FileEncoder) -> LazyTable<I, T> {
let pos = buf.position();

if T::IS_DEF_PATH_HASH {
if self.blocks.is_empty() {
return LazyTable::from_position_and_encoded_size(
NonZeroUsize::new(pos).unwrap(),
0,
0,
);
}
let mut prefix: Option<[u8; 8]> = None;
for block in self.blocks.iter() {
if prefix.is_none() {
prefix = Some(block[..8].try_into().unwrap());
}
assert_eq!(prefix.unwrap(), block[..8]);
}
buf.write_array(prefix.unwrap());

for block in &self.blocks {
buf.write_with::<8>(|dest| {
*dest = block[8..].try_into().unwrap();
8
});
}

return LazyTable::from_position_and_encoded_size(
NonZeroUsize::new(pos).unwrap(),
0,
self.blocks.len(),
);
}

let width = self.width;
for block in &self.blocks {
buf.write_with(|dest| {
Expand Down Expand Up @@ -516,6 +557,17 @@ where
return Default::default();
}

if T::IS_DEF_PATH_HASH {
let region = &metadata.blob()[self.position.get()..];
let prefix: [u8; 8] = region[..8].try_into().unwrap();
let local_hash_region = &region[8..];
let suffix: [u8; 8] = local_hash_region[i.index() * 8..][..8].try_into().unwrap();
let mut combined = [0; 16];
combined[..8].copy_from_slice(&prefix);
combined[8..].copy_from_slice(&suffix);
return FixedSizeEncoding::from_16_bytes(&combined);
}

let width = self.width;
let start = self.position.get() + (width * i.index());
let end = start + width;
Expand Down

0 comments on commit 5b3116c

Please sign in to comment.