Skip to content
Snippets Groups Projects
Unverified Commit bde4250c authored by Yorick Peterse's avatar Yorick Peterse
Browse files

Make ArcWithoutWeak NonNull

This reduces the size of an Option<ArcWithoutWeak<T>> from 16 bytes to
just 8 bytes. This in turn can save a decent amount of memory when
allocating many closures.
parent 60d86364
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -6,6 +6,7 @@
use std::cmp;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use std::sync::atomic::{AtomicUsize, Ordering};
 
/// The inner value of a pointer.
Loading
Loading
@@ -21,7 +22,7 @@ pub struct Inner<T> {
 
/// A thread-safe reference counted pointer.
pub struct ArcWithoutWeak<T> {
inner: *mut Inner<T>,
inner: NonNull<Inner<T>>,
}
 
unsafe impl<T> Sync for ArcWithoutWeak<T> {}
Loading
Loading
@@ -38,7 +39,7 @@ impl<T> ArcWithoutWeak<T> {
 
mem::forget(value);
 
raw as *mut T
raw.as_ptr() as _
}
 
/// Constructs an `ArcWithoutWeak` from a raw pointer.
Loading
Loading
@@ -48,7 +49,7 @@ impl<T> ArcWithoutWeak<T> {
/// `ArcWithoutWeak::into_raw()`.
pub unsafe fn from_raw(value: *mut T) -> Self {
ArcWithoutWeak {
inner: value as *mut Inner<T>,
inner: NonNull::new_unchecked(value as *mut Inner<T>),
}
}
 
Loading
Loading
@@ -59,12 +60,14 @@ impl<T> ArcWithoutWeak<T> {
};
 
ArcWithoutWeak {
inner: Box::into_raw(Box::new(inner)),
inner: unsafe {
NonNull::new_unchecked(Box::into_raw(Box::new(inner)))
},
}
}
 
pub fn inner(&self) -> &Inner<T> {
unsafe { &(*self.inner) }
unsafe { self.inner.as_ref() }
}
 
pub fn references(&self) -> usize {
Loading
Loading
@@ -72,7 +75,7 @@ impl<T> ArcWithoutWeak<T> {
}
 
pub fn as_ptr(&self) -> *mut T {
self.inner as *mut T
self.inner.as_ptr() as _
}
}
 
Loading
Loading
@@ -86,7 +89,7 @@ impl<T> Deref for ArcWithoutWeak<T> {
 
impl<T> DerefMut for ArcWithoutWeak<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut (*self.inner).value }
unsafe { &mut self.inner.as_mut().value }
}
}
 
Loading
Loading
@@ -102,7 +105,7 @@ impl<T> Drop for ArcWithoutWeak<T> {
fn drop(&mut self) {
unsafe {
if self.inner().references.fetch_sub(1, Ordering::AcqRel) == 1 {
let boxed = Box::from_raw(self.inner as *mut Inner<T>);
let boxed = Box::from_raw(self.inner.as_mut());
 
drop(boxed);
}
Loading
Loading
@@ -133,6 +136,7 @@ impl<T: Eq> Eq for ArcWithoutWeak<T> {}
#[cfg(test)]
mod tests {
use super::*;
use std::mem;
 
#[test]
fn test_deref() {
Loading
Loading
@@ -188,4 +192,9 @@ mod tests {
assert!(foo == foo);
assert!(foo != bar);
}
#[test]
fn test_optional_type_type() {
assert_eq!(mem::size_of::<ArcWithoutWeak<()>>(), 8);
}
}
Loading
Loading
@@ -4,7 +4,7 @@ use crate::deref_pointer::DerefPointer;
use crate::object_pointer::ObjectPointer;
use crate::vm::instruction::Instruction;
 
/// An immutable, reference counted CompiledCode.
/// A pointer to a CompiledCode object.
pub type CompiledCodePointer = DerefPointer<CompiledCode>;
 
/// Structure for storing compiled code information.
Loading
Loading
Loading
Loading
@@ -151,7 +151,7 @@ pub struct Block {
/// The memory to use for the mark bitmap and allocating objects. The first
/// 128 bytes of this field are reserved and used for storing a BlockHeader.
///
/// Memory is aligned to 32 KB.
/// Memory is aligned to the block size.
pub lines: RawObjectPointer,
 
/// A flag that is set to true when this block is being finalized. This flag
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment