Skip to content

Commit c4c2b4e

Browse files
committed
core: ptr: Add helpers for pointer tagging
Add tag() convenience methods for *const T and *mut T. The methods can be used to extract the tag from the pointer. Add with_tag() convenience methods for *const T *mut T. The methods can be used to create a new pointer based on the old one, but with the high bits set to the provided tag. The helpers are intended for use with AArch64 Top-Byte Ignore and similar architecture features, specifically for writing tagging memory allocators.
1 parent c22a421 commit c4c2b4e

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

library/core/src/ptr/const_ptr.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,35 @@ impl<T: ?Sized> *const T {
15331533
// 2. ensure that `align_offset` (in `const_impl`) doesn't actually try to compute an offset.
15341534
const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl)
15351535
}
1536+
1537+
/// Returns the tag of a pointer.
1538+
///
1539+
/// Intended for use with architecture features like AArch64 TBI.
1540+
#[must_use]
1541+
#[inline]
1542+
#[unstable(feature = "ptr_tag", issue = "none")]
1543+
pub fn tag(self) -> u8 {
1544+
(self.addr() >> 56) as u8
1545+
}
1546+
1547+
/// Sets the tag of a pointer to the provided value.
1548+
///
1549+
/// Intended for use with pointer tagging architecture features such as AArch64 TBI.
1550+
///
1551+
/// SAFETY: Within Rust's memory model, this method offsets the pointer outside of
1552+
/// the bounds of its original allocation, making any use of it Undefined Behaviour.
1553+
///
1554+
/// This is only designed to be a helper method for writing tagging allocators.
1555+
/// Users *must* ensure that code using this method simulates a realloc from the untagged
1556+
/// address to the tagged address, and that the underlying memory is only ever accessed
1557+
/// using the tagged address from there onwards. Anything short of that explicitly violates the
1558+
/// Rust memory model and will cause the program to break in unexpected ways.
1559+
#[must_use]
1560+
#[inline]
1561+
#[unstable(feature = "ptr_tag", issue = "none")]
1562+
pub unsafe fn with_tag(self, tag: u8) -> Self {
1563+
self.map_addr(|addr| (addr & 0x00ffffffffffffff) | (tag as usize) << 56)
1564+
}
15361565
}
15371566

15381567
impl<T> *const [T] {

library/core/src/ptr/mut_ptr.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,35 @@ impl<T: ?Sized> *mut T {
17831783
// 2. ensure that `align_offset` (in `const_impl`) doesn't actually try to compute an offset.
17841784
const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl)
17851785
}
1786+
1787+
/// Returns the tag of a pointer.
1788+
///
1789+
/// Intended for use with architecture features like AArch64 TBI.
1790+
#[must_use]
1791+
#[inline]
1792+
#[unstable(feature = "ptr_tag", issue = "none")]
1793+
pub fn tag(self) -> u8 {
1794+
(self.addr() >> 56) as u8
1795+
}
1796+
1797+
/// Sets the tag of a pointer to the provided value.
1798+
///
1799+
/// Intended for use with pointer tagging architecture features such as AArch64 TBI.
1800+
///
1801+
/// SAFETY: Within Rust's memory model, this method offsets the pointer outside of
1802+
/// the bounds of its original allocation, making any use of it Undefined Behaviour.
1803+
///
1804+
/// This is only designed to be a helper method for writing tagging allocators.
1805+
/// Users *must* ensure that code using this method simulates a realloc from the untagged
1806+
/// address to the tagged address, and that the underlying memory is only ever accessed
1807+
/// using the tagged address from there onwards. Anything short of that explicitly violates the
1808+
/// Rust memory model and will cause the program to break in unexpected ways.
1809+
#[must_use]
1810+
#[inline]
1811+
#[unstable(feature = "ptr_tag", issue = "none")]
1812+
pub unsafe fn with_tag(self, tag: u8) -> Self {
1813+
self.map_addr(|addr| (addr & 0x00ffffffffffffff) | (tag as usize) << 56)
1814+
}
17861815
}
17871816

17881817
impl<T> *mut [T] {

0 commit comments

Comments
 (0)