aligned function pointers

This commit is contained in:
Janis 2025-02-21 23:55:05 +01:00
parent 60942daca5
commit 44acdd7873
2 changed files with 15 additions and 2 deletions

View file

@ -4,6 +4,7 @@
debug_closure_helpers, debug_closure_helpers,
cell_update, cell_update,
cold_path, cold_path,
fn_align,
let_chains let_chains
)] )]

View file

@ -66,6 +66,10 @@ mod util {
} }
} }
// Miri doesn't like tagging pointers that it doesn't know the alignment of.
// This includes function pointers, which aren't guaranteed to be aligned to
// anything, but generally have an alignment of 8, and can be specified to
// be aligned to `n` with `#[repr(align(n))]`.
#[repr(transparent)] #[repr(transparent)]
pub struct TaggedAtomicPtr<T, const BITS: usize>(AtomicPtr<()>, PhantomData<T>); pub struct TaggedAtomicPtr<T, const BITS: usize>(AtomicPtr<()>, PhantomData<T>);
@ -85,7 +89,12 @@ mod util {
pub fn ptr(&self, order: Ordering) -> NonNull<T> { pub fn ptr(&self, order: Ordering) -> NonNull<T> {
unsafe { unsafe {
NonNull::new_unchecked(self.0.load(order).map_addr(|addr| addr & !Self::mask()) as _) NonNull::new_unchecked(
self.0
.load(order)
.map_addr(|addr| addr & !Self::mask())
.cast(),
)
} }
} }
@ -180,7 +189,7 @@ mod util {
let mask = Self::mask(); let mask = Self::mask();
loop { loop {
let ptr = self.0.load(failure); let ptr = self.0.load(failure);
let new = ptr.with_addr((ptr.addr() & !mask) | (tag & mask)); let new = ptr.map_addr(|addr| (addr & !mask) | (tag & mask));
if self if self
.0 .0
@ -823,6 +832,7 @@ mod job {
F: FnOnce(&super::Scope) -> T + Send, F: FnOnce(&super::Scope) -> T + Send,
T: Send, T: Send,
{ {
#[repr(align(8))]
unsafe fn harness<F, T>(this: *const (), job: *const Job<()>, scope: &super::Scope) unsafe fn harness<F, T>(this: *const (), job: *const Job<()>, scope: &super::Scope)
where where
F: FnOnce(&super::Scope) -> T + Send, F: FnOnce(&super::Scope) -> T + Send,
@ -864,6 +874,7 @@ mod job {
F: FnOnce(&super::Scope) -> T + Send, F: FnOnce(&super::Scope) -> T + Send,
T: Send, T: Send,
{ {
#[repr(align(8))]
unsafe fn harness<F, T>(this: *const (), job: *const Job<()>, scope: &super::Scope) unsafe fn harness<F, T>(this: *const (), job: *const Job<()>, scope: &super::Scope)
where where
F: FnOnce(&super::Scope) -> T + Send, F: FnOnce(&super::Scope) -> T + Send,
@ -1117,6 +1128,7 @@ impl Scope {
let this = SendPtr::new(&raw const *self as *mut Self).unwrap(); let this = SendPtr::new(&raw const *self as *mut Self).unwrap();
let schedule = move |runnable: Runnable| { let schedule = move |runnable: Runnable| {
#[repr(align(8))]
unsafe fn harness<T>(this: *const (), job: *const Job<T>, _: &Scope) { unsafe fn harness<T>(this: *const (), job: *const Job<T>, _: &Scope) {
let runnable = Runnable::<()>::from_raw(NonNull::new_unchecked(this.cast_mut())); let runnable = Runnable::<()>::from_raw(NonNull::new_unchecked(this.cast_mut()));
runnable.run(); runnable.run();