pub struct CopyTaggedPtr<P, T, const COMPARE_PACKED: bool>{
packed: NonNull<P::Target>,
tag_ghost: PhantomData<T>,
}
Expand description
A Copy
tagged pointer.
This is essentially { pointer: P, tag: T }
packed in a single pointer.
You should use this instead of the TaggedPtr
type in all cases where
P
implements Copy
.
If COMPARE_PACKED
is true, then the pointers will be compared and hashed without
unpacking. Otherwise we don’t implement PartialEq
, Eq
and Hash
;
if you want that, wrap the CopyTaggedPtr
.
Fields§
§packed: NonNull<P::Target>
This is semantically a pair of pointer: P
and tag: T
fields,
however we pack them in a single pointer, to save space.
We pack the tag into the most-significant bits of the pointer to ease retrieval of the value. A left shift is a multiplication and those are embeddable in instruction encoding, for example:
// (<https://godbolt.org/z/jqcYPWEr3>)
example::shift_read3:
mov eax, dword ptr [8*rdi]
ret
example::mask_read3:
and rdi, -8
mov eax, dword ptr [rdi]
ret
This is ASM outputted by rustc for reads of values behind tagged pointers for different approaches of tagging:
shift_read3
uses<< 3
(the tag is in the most-significant bits)mask_read3
uses& !0b111
(the tag is in the least-significant bits)
The shift approach thus produces less instructions and is likely faster (see https://godbolt.org/z/Y913sMdWb).
Encoding diagram:
[ packed.addr ]
[ tag ] [ pointer.addr >> T::BITS ] <-- usize::BITS - T::BITS bits
^
|
T::BITS bits
The tag can be retrieved by packed.addr() >> T::BITS
and the pointer
can be retrieved by packed.map_addr(|addr| addr << T::BITS)
.
tag_ghost: PhantomData<T>
Implementations§
source§impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP>
const TAG_BIT_SHIFT: u32 = _
const ASSERTION: () = _
sourcepub fn new(pointer: P, tag: T) -> Self
pub fn new(pointer: P, tag: T) -> Self
Tags pointer
with tag
.
Note that this leaks pointer
: it won’t be dropped when
CopyTaggedPtr
is dropped. If you have a pointer with a significant
drop, use TaggedPtr
instead.
sourcefn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target>
fn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target>
Pack pointer ptr
that comes from P::into_ptr
with a tag
,
according to self.packed
encoding scheme.
sourcepub(super) fn pointer_raw(&self) -> NonNull<P::Target>
pub(super) fn pointer_raw(&self) -> NonNull<P::Target>
Retrieves the original raw pointer from self.packed
.
sourcepub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R
pub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R
This provides a reference to the P
pointer itself, rather than the
Deref::Target
. It is used for cases where we want to call methods
that may be implement differently for the Pointer than the Pointee
(e.g., Rc::clone
vs cloning the inner value).
Trait Implementations§
source§impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP>
source§impl<P, T, const CP: bool> Debug for CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> Debug for CopyTaggedPtr<P, T, CP>
source§impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP>
source§impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP>
source§impl<P, T> Hash for CopyTaggedPtr<P, T, true>
impl<P, T> Hash for CopyTaggedPtr<P, T, true>
source§impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP>
impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP>
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher)
source§impl<P, T> PartialEq for CopyTaggedPtr<P, T, true>
impl<P, T> PartialEq for CopyTaggedPtr<P, T, true>
impl<P, T, const CP: bool> Copy for CopyTaggedPtr<P, T, CP>
impl<P: Send + Pointer, T: Send + Tag, const CP: bool> DynSend for CopyTaggedPtr<P, T, CP>
impl<P: Sync + Pointer, T: Sync + Tag, const CP: bool> DynSync for CopyTaggedPtr<P, T, CP>
impl<P, T> Eq for CopyTaggedPtr<P, T, true>
impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP>
impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP>
Auto Trait Implementations§
impl<P, T, const COMPARE_PACKED: bool> Freeze for CopyTaggedPtr<P, T, COMPARE_PACKED>
impl<P, T, const COMPARE_PACKED: bool> RefUnwindSafe for CopyTaggedPtr<P, T, COMPARE_PACKED>
impl<P, T, const COMPARE_PACKED: bool> Unpin for CopyTaggedPtr<P, T, COMPARE_PACKED>where
T: Unpin,
impl<P, T, const COMPARE_PACKED: bool> UnwindSafe for CopyTaggedPtr<P, T, COMPARE_PACKED>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
Layout§
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.