Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 12fd610

Browse files
committed
Refactor tagged ptr packing into a function
1 parent 3c6f4c1 commit 12fd610

File tree

1 file changed

+22
-23
lines changed
  • compiler/rustc_data_structures/src/tagged_ptr

1 file changed

+22
-23
lines changed

compiler/rustc_data_structures/src/tagged_ptr/copy.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ where
5050
P: Pointer,
5151
T: Tag,
5252
{
53+
pub fn new(pointer: P, tag: T) -> Self {
54+
Self { packed: Self::pack(P::into_ptr(pointer), tag), data: PhantomData }
55+
}
56+
5357
const TAG_BIT_SHIFT: usize = usize::BITS as usize - T::BITS;
5458
const ASSERTION: () = {
5559
assert!(T::BITS <= P::BITS);
@@ -58,28 +62,28 @@ where
5862
assert!(std::mem::size_of::<&P::Target>() == std::mem::size_of::<usize>());
5963
};
6064

61-
pub fn new(pointer: P, tag: T) -> Self {
65+
/// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`.
66+
///
67+
/// [`P::into_ptr`]: Pointer::into_ptr
68+
fn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target> {
6269
// Trigger assert!
6370
let () = Self::ASSERTION;
6471

6572
let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT;
6673

67-
Self {
68-
packed: P::into_ptr(pointer).map_addr(|addr| {
69-
// SAFETY:
70-
// - The pointer is `NonNull` => it's address is `NonZeroUsize`
71-
// - `P::BITS` least significant bits are always zero (`Pointer` contract)
72-
// - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
73-
//
74-
// Thus `addr >> T::BITS` is guaranteed to be non-zero.
75-
//
76-
// `{non_zero} | packed_tag` can't make the value zero.
77-
78-
let packed = (addr.get() >> T::BITS) | packed_tag;
79-
unsafe { NonZeroUsize::new_unchecked(packed) }
80-
}),
81-
data: PhantomData,
82-
}
74+
ptr.map_addr(|addr| {
75+
// SAFETY:
76+
// - The pointer is `NonNull` => it's address is `NonZeroUsize`
77+
// - `P::BITS` least significant bits are always zero (`Pointer` contract)
78+
// - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
79+
//
80+
// Thus `addr >> T::BITS` is guaranteed to be non-zero.
81+
//
82+
// `{non_zero} | packed_tag` can't make the value zero.
83+
84+
let packed = (addr.get() >> T::BITS) | packed_tag;
85+
unsafe { NonZeroUsize::new_unchecked(packed) }
86+
})
8387
}
8488

8589
pub(super) fn pointer_raw(&self) -> NonNull<P::Target> {
@@ -117,12 +121,7 @@ where
117121

118122
#[inline]
119123
pub fn set_tag(&mut self, tag: T) {
120-
// TODO: refactor packing into a function and reuse it here
121-
let new_tag = T::into_usize(tag) << Self::TAG_BIT_SHIFT;
122-
let tag_mask = (1 << T::BITS) - 1;
123-
self.packed = self.packed.map_addr(|addr| unsafe {
124-
NonZeroUsize::new_unchecked(addr.get() & !(tag_mask << Self::TAG_BIT_SHIFT) | new_tag)
125-
});
124+
self.packed = Self::pack(self.pointer_raw(), tag);
126125
}
127126
}
128127

0 commit comments

Comments
 (0)