Last active
February 16, 2025 00:57
-
-
Save lovely-error/3d89fe6fe55755a8c2c8c07975f94603 to your computer and use it in GitHub Desktop.
tagged ptr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::marker::PhantomData; | |
use core::mem::ManuallyDrop; | |
#[repr(C)] #[derive(Copy, Clone)] | |
union TaggedPtr64Repr<T> { | |
num: u64, | |
tag: ManuallyDrop<T>, | |
} | |
struct TaggedPtr64<Tag, Target>(u64, PhantomData<(*mut Target ,Tag)>); | |
impl <T, P> TaggedPtr64<T, P> { | |
fn pack( | |
tag: T, | |
ptr: *mut P | |
) -> Self { | |
const { | |
assert!(size_of::<T>() <= 2, "Invalid tag size"); | |
assert!(align_of::<T>() <= 8, "Invalid tag align"); | |
} | |
let ptr = (ptr as u64) << 16; | |
let mut val = TaggedPtr64Repr { num: ptr }; | |
val.tag = ManuallyDrop::new(tag); | |
let val = unsafe { val.num }; | |
return Self(val, PhantomData); | |
} | |
fn unpack(self) -> (T, *mut P) { | |
let Self(val, _) = self; | |
let val = TaggedPtr64Repr { num: val }; | |
let ptr = unsafe { val.num } >> 16; | |
let ptr = ptr as *mut P; | |
let tag = unsafe { val.tag }; | |
let tag = ManuallyDrop::into_inner(tag); | |
return (tag, ptr); | |
} | |
pub fn tag_ref(&mut self) -> &mut T { | |
unsafe { transmute(self) } | |
} | |
} | |
impl <T, P> Clone for TaggedPtr64<T, P> where T: Copy { | |
fn clone(&self) -> Self { | |
Self(self.0, PhantomData) | |
} | |
} | |
impl <T, P> Copy for TaggedPtr64<T, P> where T: Copy {} | |
fn main () { | |
let mut val = 13137; | |
let ptr = TaggedPtr64::pack(13137u16, &mut val); | |
let a@(tag, ptr) = ptr.unpack(); | |
println!("{:?}", a); | |
assert!(tag == 13137 && ptr == &mut val); | |
assert!(unsafe { *ptr } == 13137); | |
let mut ptr = TaggedPtr64::pack(tag, unsafe {&mut *ptr}); | |
*ptr.tag_ref() += 1; | |
let a@(tag, ptr) = ptr.unpack(); | |
println!("{:?}", a); | |
assert!(tag == 13138); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment