use parking_lot::Mutex;
use std::sync::Arc;
pub(crate) struct Allocations {
allocations: Mutex<Vec<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 p in self.allocations.lock().iter().rev().copied() {
unsafe { drop(Box::from_raw(p as *mut usize)) };
}
}
}
impl Allocations {
pub(super) unsafe fn new() -> Arc<Self> {
Arc::new(Self {
allocations: Mutex::new(vec![]),
})
}
pub(super) fn bref<T>(&self, v: Box<T>) -> &'static T {
let p = Box::into_raw(v);
if (p as usize) < 16 {
panic!("bref bad ptr");
}
self.allocations.lock().push(p as usize);
Box::leak(unsafe { Box::from_raw(p) })
}
pub(super) 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");
}
self.allocations.lock().push(p as usize);
Box::leak(unsafe { Box::from_raw(p) })
}
fn bref_slice<T>(&self, v: Box<[T]>) -> &'static [T] {
if !v.is_empty() {
self.allocations.lock().push(v.as_ptr() as usize);
}
Box::leak(v)
}
pub(super) fn sref_vec<T>(&self, v: Vec<T>) -> &'static [T] {
self.bref_slice(v.into_boxed_slice())
}
pub(super) fn sref_slice<T>(&self, v: T) -> &'static [&'static T] {
self.bref_slice(vec![self.sref(v)].into_boxed_slice())
}
}