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

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

@ -24,13 +24,16 @@
*
*/
use core::{
fmt,
hash::{Hash, Hasher},
iter::FusedIterator,
mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr, slice,
use {
crate::engine::mem::unsafe_apis,
core::{
fmt,
hash::{Hash, Hasher},
iter::FusedIterator,
mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr, slice,
},
};
pub struct UArray<const N: usize, T> {
@ -88,9 +91,8 @@ impl<const N: usize, T> UArray<N, T> {
}
pub fn clear(&mut self) {
unsafe {
let ptr = self.as_slice_mut();
// 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
self.set_len(0);
}
@ -176,7 +178,7 @@ impl<const N: usize, T> Drop for UArray<N, T> {
if !self.is_empty() {
unsafe {
// 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 len = self.l - self.i;
// 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 {
let ptr = alloc::alloc(layout);
assert!(!ptr.is_null(), "malloc failed");
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 {
self::alloc_layout(Layout::array::<T>(l).unwrap_unchecked())
}
/// Deallocate the given layout
pub unsafe fn dealloc_layout(ptr: *mut u8, layout: 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) {
if l != 0 {
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] {
let mut dst = [0u8; N];
src.as_ptr().copy_to_nonoverlapping(dst.as_mut_ptr(), N);

@ -24,13 +24,15 @@
*
*/
use std::{
alloc::{alloc, dealloc, Layout},
fmt,
iter::FusedIterator,
mem::{self, ManuallyDrop, MaybeUninit},
ops::{Deref, DerefMut},
ptr, slice,
use {
super::unsafe_apis,
std::{
fmt,
iter::FusedIterator,
mem::{self, ManuallyDrop, MaybeUninit},
ops::{Deref, DerefMut},
ptr, slice,
},
};
union VData<const N: usize, T> {
@ -77,7 +79,7 @@ impl<const N: usize, T> VInline<N, T> {
pub fn clear(&mut self) {
unsafe {
// 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;
}
@ -171,19 +173,13 @@ impl<const N: usize, T> VInline<N, T> {
}
}
#[inline(always)]
fn layout(cap: usize) -> Layout {
Layout::array::<T>(cap).unwrap()
}
#[inline(always)]
fn ncap(&self) -> usize {
self.c * Self::ALLOC_MULTIPLIER
}
fn alloc_block(cap: usize) -> *mut T {
unsafe {
// UNSAFE(@ohsayan): malloc bro
let p = alloc(Self::layout(cap));
assert!(!p.is_null(), "alloc,0");
p as *mut T
// UNSAFE(@ohsayan): this is a malloc
unsafe_apis::alloc_array(cap)
}
}
pub unsafe fn push_unchecked(&mut self, v: T) {
@ -248,7 +244,7 @@ impl<const N: usize, T> VInline<N, T> {
}
#[inline(always)]
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) {
unsafe {
// 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() {
// UNSAFE(@ohsayan): non-null heap
self.dealloc_heap(self.d.h);
@ -357,10 +353,7 @@ impl<const N: usize, T> Drop for IntoIter<N, T> {
// sweet
unsafe {
// 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(
self.v._as_mut_ptr().add(self.i),
self.l - self.i,
))
unsafe_apis::drop_slice_in_place(self.v._as_mut_ptr().add(self.i), self.l - self.i)
}
}
}

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

Loading…
Cancel
Save