use parking_lot::Mutex;
use std::sync::Arc;
pub(crate) struct Allocations {
allocations: Mutex<Vec<Allocation>>,
}
#[derive(Debug, Copy, Clone)]
pub(crate) struct Allocation {
ptr: usize,
len: usize,
}
impl std::fmt::Debug for Allocations {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Allocations").finish()
}
}
impl Drop for Allocations {
fn drop(&mut self) {
log::debug!(
"freeing allocations of length {}",
self.allocations.lock().len()
);
for a in self.allocations.lock().iter().rev().copied() {
log::debug!("freeing ptr 0x{:x} len{}", a.ptr, a.len);
unsafe {
drop(Box::<[u8]>::from_raw(std::ptr::slice_from_raw_parts_mut(
a.ptr as *mut u8,
a.len,
)))
};
}
}
}
impl Allocations {
pub(crate) unsafe fn new() -> Arc<Self> {
Arc::new(Self {
allocations: Mutex::new(vec![]),
})
}
pub(crate) fn sref<T>(&self, v: T) -> &'static T {
let p = Box::into_raw(Box::new(v));
if (p as usize) < 16 {
panic!("sref bad ptr");
}
log::debug!(
"sref type: {}, ptr:{p:?} sz:{}",
std::any::type_name::<T>(),
std::mem::size_of::<T>()
);
self.allocations.lock().push(Allocation {
ptr: p as usize,
len: std::mem::size_of::<T>(),
});
Box::leak(unsafe { Box::from_raw(p) })
}
pub(crate) fn bref_slice<T>(&self, v: Box<[T]>) -> &'static [T] {
if !v.is_empty() {
let p = v.as_ptr();
log::debug!(
"bref_slice type: {}, ptr:{p:?} sz:{}",
std::any::type_name::<T>(),
std::mem::size_of::<T>()
);
self.allocations.lock().push(Allocation {
ptr: p as usize,
len: std::mem::size_of::<T>() * v.len(),
});
}
Box::leak(v)
}
pub(crate) fn sref_vec<T>(&self, v: Vec<T>) -> &'static [T] {
log::debug!("sref_vec {}", std::any::type_name::<T>());
self.bref_slice(v.into_boxed_slice())
}
pub(crate) fn sref_slice<T>(&self, v: T) -> &'static [&'static T] {
log::debug!("sref_slice {}", std::any::type_name::<T>());
self.bref_slice(vec![self.sref(v)].into_boxed_slice())
}
pub(crate) fn sref_str(&self, v: String) -> &'static str {
if !v.capacity() == 0 {
""
} else {
let len = v.len();
let s = v.leak();
self.allocations.lock().push(Allocation {
ptr: s.as_ptr() as usize,
len,
});
s
}
}
}