Use common memory APIs

next
Sayan Nandan 8 months ago
parent 843adbaf7e
commit c5044c592f
No known key found for this signature in database
GPG Key ID: 0EBD769024B24F0A

@ -24,14 +24,9 @@
* *
*/ */
use std::{ use {
alloc::{dealloc, Layout}, crate::engine::mem::unsafe_apis,
borrow::Borrow, std::{borrow::Borrow, fmt, hash::Hash, marker::PhantomData, mem::ManuallyDrop, slice, str},
fmt,
hash::Hash,
marker::PhantomData,
mem::ManuallyDrop,
slice, str,
}; };
pub struct EntityID { pub struct EntityID {
@ -63,8 +58,8 @@ impl EntityID {
impl Drop for EntityID { impl Drop for EntityID {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
dealloc(self.sp, Layout::array::<u8>(self.sl).unwrap_unchecked()); unsafe_apis::dealloc_array(self.sp, self.sl);
dealloc(self.ep, Layout::array::<u8>(self.el).unwrap_unchecked()); unsafe_apis::dealloc_array(self.ep, self.el);
} }
} }
} }

@ -38,9 +38,9 @@ use {
super::{ super::{
AsKey, AsKeyClone, AsValue, AsValueClone, IndexBaseSpec, STIndex, STIndexExt, STIndexSeq, AsKey, AsKeyClone, AsValue, AsValueClone, IndexBaseSpec, STIndex, STIndexExt, STIndexSeq,
}, },
crate::engine::mem::StatelessLen, crate::engine::mem::{unsafe_apis, StatelessLen},
std::{ std::{
alloc::{alloc as std_alloc, dealloc as std_dealloc, Layout}, alloc::Layout,
borrow::Borrow, borrow::Borrow,
collections::HashMap as StdMap, collections::HashMap as StdMap,
fmt::{self, Debug}, fmt::{self, Debug},
@ -163,9 +163,7 @@ impl<K, V> IndexSTSeqDllNode<K, V> {
fn _alloc_with_garbage() -> *mut Self { fn _alloc_with_garbage() -> *mut Self {
unsafe { unsafe {
// UNSAFE(@ohsayan): aight shut up, it's a malloc // UNSAFE(@ohsayan): aight shut up, it's a malloc
let ptr = std_alloc(Self::LAYOUT) as *mut Self; unsafe_apis::alloc_layout(Self::LAYOUT)
assert!(!ptr.is_null(), "damn the allocator failed");
ptr
} }
} }
#[inline(always)] #[inline(always)]
@ -191,7 +189,7 @@ impl<K, V> IndexSTSeqDllNode<K, V> {
#[inline(always)] #[inline(always)]
/// LEAK: K, V /// LEAK: K, V
unsafe fn dealloc_headless(slf: *mut Self) { unsafe fn dealloc_headless(slf: *mut Self) {
std_dealloc(slf as *mut u8, Self::LAYOUT) unsafe_apis::dealloc_layout(slf as *mut u8, Self::LAYOUT)
} }
#[inline(always)] #[inline(always)]
unsafe fn unlink(node: *mut Self) { unsafe fn unlink(node: *mut Self) {

@ -24,13 +24,16 @@
* *
*/ */
use core::{ use {
fmt, crate::engine::mem::unsafe_apis,
hash::{Hash, Hasher}, core::{
iter::FusedIterator, fmt,
mem::MaybeUninit, hash::{Hash, Hasher},
ops::{Deref, DerefMut}, iter::FusedIterator,
ptr, slice, mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr, slice,
},
}; };
pub struct UArray<const N: usize, T> { pub struct UArray<const N: usize, T> {
@ -88,9 +91,8 @@ impl<const N: usize, T> UArray<N, T> {
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
unsafe { unsafe {
let ptr = self.as_slice_mut();
// UNSAFE(@ohsayan): We know this is the initialized length // UNSAFE(@ohsayan): We know this is the initialized length
ptr::drop_in_place(ptr); unsafe_apis::drop_slice_in_place_ref(self.as_slice_mut());
// UNSAFE(@ohsayan): we've destroyed everything, so yeah, all g // UNSAFE(@ohsayan): we've destroyed everything, so yeah, all g
self.set_len(0); self.set_len(0);
} }
@ -176,7 +178,7 @@ impl<const N: usize, T> Drop for UArray<N, T> {
if !self.is_empty() { if !self.is_empty() {
unsafe { unsafe {
// UNSAFE(@ohsayan): as_slice_mut returns a correct offset // UNSAFE(@ohsayan): as_slice_mut returns a correct offset
ptr::drop_in_place(self.as_slice_mut()) unsafe_apis::drop_slice_in_place_ref(self.as_slice_mut())
} }
} }
} }
@ -263,7 +265,7 @@ impl<const N: usize, T> Drop for IntoIter<N, T> {
let ptr = self.d.a.as_mut_ptr().add(self.i) as *mut T; let ptr = self.d.a.as_mut_ptr().add(self.i) as *mut T;
let len = self.l - self.i; let len = self.l - self.i;
// UNSAFE(@ohsayan): we know the segment to drop // UNSAFE(@ohsayan): we know the segment to drop
ptr::drop_in_place(ptr::slice_from_raw_parts_mut(ptr, len)) unsafe_apis::drop_slice_in_place(ptr, len)
} }
} }
} }

@ -24,28 +24,54 @@
* *
*/ */
use std::alloc::{self, Layout}; /*!
# Unsafe APIs
This module provides abstractions (unsafe, still) over unsafe allocator and related APIs.
*/
use std::{
alloc::{self, Layout},
ptr,
};
/// Allocate the given layout. This will panic if the allocator returns an error
pub unsafe fn alloc_layout<T>(layout: Layout) -> *mut T { pub unsafe fn alloc_layout<T>(layout: Layout) -> *mut T {
let ptr = alloc::alloc(layout); let ptr = alloc::alloc(layout);
assert!(!ptr.is_null(), "malloc failed"); assert!(!ptr.is_null(), "malloc failed");
ptr as _ ptr as _
} }
/// Allocate an block with an array layout of type `T` with space for `l` elements
pub unsafe fn alloc_array<T>(l: usize) -> *mut T { pub unsafe fn alloc_array<T>(l: usize) -> *mut T {
self::alloc_layout(Layout::array::<T>(l).unwrap_unchecked()) self::alloc_layout(Layout::array::<T>(l).unwrap_unchecked())
} }
/// Deallocate the given layout
pub unsafe fn dealloc_layout(ptr: *mut u8, layout: Layout) { pub unsafe fn dealloc_layout(ptr: *mut u8, layout: Layout) {
alloc::dealloc(ptr, layout) alloc::dealloc(ptr, layout)
} }
/// Deallocate an array of type `T` with size `l`. This function will ensure that nonzero calls to the
/// allocator are made
pub unsafe fn dealloc_array<T>(ptr: *mut T, l: usize) { pub unsafe fn dealloc_array<T>(ptr: *mut T, l: usize) {
if l != 0 { if l != 0 {
self::dealloc_layout(ptr as *mut u8, Layout::array::<T>(l).unwrap_unchecked()) self::dealloc_layout(ptr as *mut u8, Layout::array::<T>(l).unwrap_unchecked())
} }
} }
/// Run the dtor for the given slice (range)
pub unsafe fn drop_slice_in_place_ref<T>(ptr: &mut [T]) {
ptr::drop_in_place(ptr as *mut [T])
}
/// Run the dtor for the given slice (defined using ptr and len)
pub unsafe fn drop_slice_in_place<T>(ptr: *mut T, l: usize) {
ptr::drop_in_place(ptr::slice_from_raw_parts_mut(ptr, l))
}
/// Copy exactly `N` bytes from `src` to a new array of size `N`
pub unsafe fn memcpy<const N: usize>(src: &[u8]) -> [u8; N] { pub unsafe fn memcpy<const N: usize>(src: &[u8]) -> [u8; N] {
let mut dst = [0u8; N]; let mut dst = [0u8; N];
src.as_ptr().copy_to_nonoverlapping(dst.as_mut_ptr(), N); src.as_ptr().copy_to_nonoverlapping(dst.as_mut_ptr(), N);

@ -24,13 +24,15 @@
* *
*/ */
use std::{ use {
alloc::{alloc, dealloc, Layout}, super::unsafe_apis,
fmt, std::{
iter::FusedIterator, fmt,
mem::{self, ManuallyDrop, MaybeUninit}, iter::FusedIterator,
ops::{Deref, DerefMut}, mem::{self, ManuallyDrop, MaybeUninit},
ptr, slice, ops::{Deref, DerefMut},
ptr, slice,
},
}; };
union VData<const N: usize, T> { union VData<const N: usize, T> {
@ -77,7 +79,7 @@ impl<const N: usize, T> VInline<N, T> {
pub fn clear(&mut self) { pub fn clear(&mut self) {
unsafe { unsafe {
// UNSAFE(@ohsayan): as_slice_mut will always give a valid ptr // UNSAFE(@ohsayan): as_slice_mut will always give a valid ptr
ptr::drop_in_place(self._as_slice_mut()); unsafe_apis::drop_slice_in_place_ref(self._as_slice_mut())
} }
self.l = 0; self.l = 0;
} }
@ -171,19 +173,13 @@ impl<const N: usize, T> VInline<N, T> {
} }
} }
#[inline(always)] #[inline(always)]
fn layout(cap: usize) -> Layout {
Layout::array::<T>(cap).unwrap()
}
#[inline(always)]
fn ncap(&self) -> usize { fn ncap(&self) -> usize {
self.c * Self::ALLOC_MULTIPLIER self.c * Self::ALLOC_MULTIPLIER
} }
fn alloc_block(cap: usize) -> *mut T { fn alloc_block(cap: usize) -> *mut T {
unsafe { unsafe {
// UNSAFE(@ohsayan): malloc bro // UNSAFE(@ohsayan): this is a malloc
let p = alloc(Self::layout(cap)); unsafe_apis::alloc_array(cap)
assert!(!p.is_null(), "alloc,0");
p as *mut T
} }
} }
pub unsafe fn push_unchecked(&mut self, v: T) { pub unsafe fn push_unchecked(&mut self, v: T) {
@ -248,7 +244,7 @@ impl<const N: usize, T> VInline<N, T> {
} }
#[inline(always)] #[inline(always)]
unsafe fn dealloc_heap(&mut self, heap: *mut T) { unsafe fn dealloc_heap(&mut self, heap: *mut T) {
dealloc(heap as *mut u8, Self::layout(self.capacity())) unsafe_apis::dealloc_array(heap, self.capacity())
} }
} }
@ -275,7 +271,7 @@ impl<const N: usize, T> Drop for VInline<N, T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
// UNSAFE(@ohsayan): correct ptr guaranteed by safe impl of _as_slice_mut() // UNSAFE(@ohsayan): correct ptr guaranteed by safe impl of _as_slice_mut()
ptr::drop_in_place(self._as_slice_mut()); unsafe_apis::drop_slice_in_place_ref(self._as_slice_mut());
if !self.on_stack() { if !self.on_stack() {
// UNSAFE(@ohsayan): non-null heap // UNSAFE(@ohsayan): non-null heap
self.dealloc_heap(self.d.h); self.dealloc_heap(self.d.h);
@ -357,10 +353,7 @@ impl<const N: usize, T> Drop for IntoIter<N, T> {
// sweet // sweet
unsafe { unsafe {
// UNSAFE(@ohsayan): Safe because we maintain the EOA cond; second, the l is the remaining part // UNSAFE(@ohsayan): Safe because we maintain the EOA cond; second, the l is the remaining part
ptr::drop_in_place(ptr::slice_from_raw_parts_mut( unsafe_apis::drop_slice_in_place(self.v._as_mut_ptr().add(self.i), self.l - self.i)
self.v._as_mut_ptr().add(self.i),
self.l - self.i,
))
} }
} }
} }

@ -26,15 +26,15 @@
use { use {
super::atm::{ORD_ACQ, ORD_REL, ORD_RLX}, super::atm::{ORD_ACQ, ORD_REL, ORD_RLX},
crate::engine::mem::unsafe_apis,
std::{ std::{
alloc::{dealloc, Layout},
borrow::Borrow, borrow::Borrow,
fmt, fmt,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
mem::{self, ManuallyDrop}, mem::{self, ManuallyDrop},
ops::Deref, ops::Deref,
process, process,
ptr::{self, NonNull}, ptr::NonNull,
slice, str, slice, str,
sync::atomic::{self, AtomicUsize}, sync::atomic::{self, AtomicUsize},
}, },
@ -141,13 +141,11 @@ impl<T> Drop for SliceRC<T> {
// dtor // dtor
if mem::needs_drop::<T>() { if mem::needs_drop::<T>() {
// UNSAFE(@ohsayan): dtor through, the ctor guarantees correct alignment and len // UNSAFE(@ohsayan): dtor through, the ctor guarantees correct alignment and len
ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len)); unsafe_apis::drop_slice_in_place(self.ptr.as_ptr(), self.len)
} }
// dealloc // dealloc
// UNSAFE(@ohsayan): we allocated it // UNSAFE(@ohsayan): we allocated it + layout structure guaranteed by ctor
let layout = Layout::array::<T>(self.len).unwrap_unchecked(); unsafe_apis::dealloc_array(self.ptr.as_ptr(), self.len)
// UNSAFE(@ohsayan): layout structure guaranteed by ctor
dealloc(self.ptr.as_ptr() as *mut u8, layout);
}) })
} }
} }

Loading…
Cancel
Save