diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index c99f09d29f..5992baf06e 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -2,13 +2,13 @@ use std::{ alloc, cell::Cell, ops::{Deref, DerefMut}, - ptr::{self, NonNull}, + ptr, rc::Rc, }; struct ArenaElement { - value: NonNull, - drop: unsafe fn(NonNull), + value: *mut u8, + drop: unsafe fn(*mut u8), } impl Drop for ArenaElement { @@ -21,8 +21,9 @@ impl Drop for ArenaElement { } pub struct Arena { - start: NonNull, - offset: usize, + start: *mut u8, + end: *mut u8, + offset: *mut u8, elements: Vec, valid: Rc>, } @@ -31,10 +32,12 @@ impl Arena { pub fn new(size_in_bytes: usize) -> Self { unsafe { let layout = alloc::Layout::from_size_align(size_in_bytes, 1).unwrap(); - let ptr = alloc::alloc(layout); + let start = alloc::alloc(layout); + let end = start.add(size_in_bytes); Self { - start: NonNull::new_unchecked(ptr), - offset: 0, + start, + end, + offset: start, elements: Vec::new(), valid: Rc::new(Cell::new(true)), } @@ -45,7 +48,7 @@ impl Arena { self.valid.set(false); self.valid = Rc::new(Cell::new(true)); self.elements.clear(); - self.offset = 0; + self.offset = self.start; } #[inline(always)] @@ -58,24 +61,28 @@ impl Arena { ptr::write(ptr, f()); } - unsafe fn drop(ptr: NonNull) { - std::ptr::drop_in_place(ptr.cast::().as_ptr()); + unsafe fn drop(ptr: *mut u8) { + std::ptr::drop_in_place(ptr.cast::()); } unsafe { let layout = alloc::Layout::new::().pad_to_align(); - let ptr = NonNull::new_unchecked(self.start.as_ptr().add(self.offset).cast::()); - inner_writer(ptr.as_ptr(), f); + let next_offset = self.offset.add(layout.size()); + assert!(next_offset <= self.end); + let result = ArenaRef { + ptr: self.offset.cast(), + valid: self.valid.clone(), + }; + + inner_writer(result.ptr, f); self.elements.push(ArenaElement { - value: ptr.cast(), + value: self.offset, drop: drop::, }); - self.offset += layout.size(); - ArenaRef { - ptr, - valid: self.valid.clone(), - } + self.offset = next_offset; + + result } } } @@ -87,7 +94,7 @@ impl Drop for Arena { } pub struct ArenaRef { - ptr: NonNull, + ptr: *mut T, valid: Rc>, } @@ -104,7 +111,7 @@ impl ArenaRef { #[inline(always)] pub fn map(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef { ArenaRef { - ptr: unsafe { NonNull::new_unchecked(f(&mut *self)) }, + ptr: f(&mut self), valid: self.valid, } } @@ -123,7 +130,7 @@ impl Deref for ArenaRef { #[inline(always)] fn deref(&self) -> &Self::Target { self.validate(); - unsafe { self.ptr.as_ref() } + unsafe { &*self.ptr } } } @@ -131,7 +138,7 @@ impl DerefMut for ArenaRef { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.validate(); - unsafe { self.ptr.as_mut() } + unsafe { &mut *self.ptr } } }