From 004f12c7655f10084311de485d13ac02eca2bc44 Mon Sep 17 00:00:00 2001 From: lifning <> Date: Sat, 27 Nov 2021 17:59:05 -0800 Subject: [PATCH] expand address space by enforcing minimum alignment of 4 --- src/main.rs | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index dd22afa..9456775 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ struct Pool { impl Default for Pool { fn default() -> Self { - let inner = Mutex::new(PoolInner { data: [0; 0x10000], begin: 0, end: 0, last_position: 0 }); + let inner = Mutex::new(PoolInner { data: [0; 0x40000], begin: 0, end: 0, last_position: 0 }); let base_ptr = inner.lock().unwrap().data.as_ptr() as usize; Pool { inner, @@ -44,9 +44,9 @@ impl std::fmt::Debug for Pool { } } -#[repr(C, align(0x10000))] +#[repr(C, align(4))] struct PoolInner { - data: [u8; 0x10000], + data: [u8; 0x40000], begin: usize, end: usize, last_position: usize, @@ -56,7 +56,7 @@ struct PoolInner { impl PoolInner { fn alloc(&mut self, layout: Layout) -> u16 { let size = layout.size(); - let align = layout.align(); + let align = layout.align().max(4); let mut position = self.end + size_of::(); // space for skip marker let alignmask = align - 1; @@ -66,7 +66,7 @@ impl PoolInner { let new_end = position + size; assert!(new_end < self.data.len(), "ShortPointer memory pool exhausted"); // using most significant bit as whether it's been freed - assert!(position - self.last_position < 32768, "Alignment caused 32KiB limit overrun"); + assert!(position - self.last_position < self.data.len() / 2, "Alignment caused pool size overrun"); let skip_marker = 0x8000_u16.to_ne_bytes(); self.data[position - 2..position].copy_from_slice(&skip_marker); @@ -74,12 +74,19 @@ impl PoolInner { if self.begin == 0 { self.begin = position; } + if self.last_position != 0 { + unsafe { + let last_skip_marker = self.data.as_mut_ptr().add(self.last_position - 2) as *mut u16; + assert_eq!(*last_skip_marker & 0x7fff, 0); + *last_skip_marker |= ((position - self.last_position) / 4) as u16; + } + } self.last_position = position; - position as u16 + (position / 4) as u16 } fn dealloc(&mut self, sptr: u16) { - let mut position = sptr as usize; + let mut position = (sptr * 4) as usize; unsafe { let skip_marker_ptr = self.data.as_mut_ptr().add(position - 2) as *mut u16; *skip_marker_ptr &= 0x7fff; @@ -89,10 +96,10 @@ impl PoolInner { while skip_marker & 0x8000 == 0 { if skip_marker == 0 { // last object, we can reclaim memory back to sptr - self.end = sptr as usize; + self.end = (sptr * 4) as usize; break; } else { - position += skip_marker as usize; + position += skip_marker as usize * 4; } skip_marker = *(self.data.as_ptr().add(position - 2) as *const u16); } @@ -105,6 +112,8 @@ impl PoolInner { self.begin = 0; self.end = 0; self.last_position = 0; + } else { + // TODO: restore self.last_position linearly from self.begin } } } @@ -132,7 +141,7 @@ impl Drop for ShortPointer { impl ShortPointer { fn deref_inner(&self) -> &mut T { unsafe { - ((POOL.base_ptr + (self.0 as usize)) as *mut T).as_mut().unwrap() + ((POOL.base_ptr + (self.0 as usize * 4)) as *mut T).as_mut().unwrap() } }