Skip to content

Commit

Permalink
Force a niche into VersionSmall
Browse files Browse the repository at this point in the history
Force a niche into the aligned type so the [`Version`] enum is two words instead of three (x86_64). Rustc currently fails to optimize this on its own.
  • Loading branch information
konstin committed Jan 8, 2025
1 parent fa305bd commit f65389d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
6 changes: 3 additions & 3 deletions crates/uv-distribution-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,10 +1343,10 @@ mod test {
/// Ensure that we don't accidentally grow the `Dist` sizes.
#[test]
fn dist_size() {
assert!(size_of::<Dist>() <= 352, "{}", size_of::<Dist>());
assert!(size_of::<BuiltDist>() <= 352, "{}", size_of::<BuiltDist>());
assert!(size_of::<Dist>() <= 344, "{}", size_of::<Dist>());
assert!(size_of::<BuiltDist>() <= 344, "{}", size_of::<BuiltDist>());
assert!(
size_of::<SourceDist>() <= 264,
size_of::<SourceDist>() <= 256,
"{}",
size_of::<SourceDist>()
);
Expand Down
18 changes: 13 additions & 5 deletions crates/uv-pep440/src/version.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::num::NonZero;
use std::ops::Deref;
use std::sync::LazyLock;
use std::{
Expand Down Expand Up @@ -933,14 +934,13 @@ impl FromStr for Version {
struct VersionSmall {
/// The number of segments in the release component.
///
/// Strictly speaking, this isn't necessary since `1.2` is considered
/// equivalent to `1.2.0.0`. But in practice it's nice to be able
/// to truncate the zero components. And always filling out to 4
/// places somewhat exposes internal details, since the "full" version
/// representation would not do that.
/// PEP 440 considers `1.2` equivalent to `1.2.0.0`, but we want to preserve trailing zeroes
/// in roundtrips, as the "full" version representation also does.
len: u8,
/// The representation discussed above.
repr: u64,
/// Force a niche into the aligned type so the [`Version`] enum is two words instead of three.
_force_niche: NonZero<u8>,
}

impl VersionSmall {
Expand Down Expand Up @@ -989,6 +989,7 @@ impl VersionSmall {
#[inline]
fn new() -> Self {
Self {
_force_niche: NonZero::<u8>::MIN,
repr: Self::SUFFIX_NONE << Self::SUFFIX_VERSION_BIT_LEN,
len: 0,
}
Expand Down Expand Up @@ -1800,6 +1801,7 @@ impl<'a> Parser<'a> {
*release.get_mut(usize::from(len))? = cur;
len += 1;
let small = VersionSmall {
_force_niche: NonZero::<u8>::MIN,
repr: (u64::from(release[0]) << 48)
| (u64::from(release[1]) << 40)
| (u64::from(release[2]) << 32)
Expand Down Expand Up @@ -4007,4 +4009,10 @@ mod tests {
assert_eq!(&*v2.release(), &[1, 2]);
assert_eq!(v2.to_string(), "1.2");
}

#[test]
fn type_size() {
assert_eq!(size_of::<VersionSmall>(), size_of::<usize>() * 2);
assert_eq!(size_of::<Version>(), size_of::<usize>() * 2);
}
}

0 comments on commit f65389d

Please sign in to comment.