expand address space by enforcing minimum alignment of 4

This commit is contained in:
lifning 2021-11-27 17:59:05 -08:00
parent 4bb748246c
commit 004f12c765

View file

@ -20,7 +20,7 @@ struct Pool {
impl Default for Pool { impl Default for Pool {
fn default() -> Self { 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; let base_ptr = inner.lock().unwrap().data.as_ptr() as usize;
Pool { Pool {
inner, inner,
@ -44,9 +44,9 @@ impl std::fmt::Debug for Pool {
} }
} }
#[repr(C, align(0x10000))] #[repr(C, align(4))]
struct PoolInner { struct PoolInner {
data: [u8; 0x10000], data: [u8; 0x40000],
begin: usize, begin: usize,
end: usize, end: usize,
last_position: usize, last_position: usize,
@ -56,7 +56,7 @@ struct PoolInner {
impl PoolInner { impl PoolInner {
fn alloc(&mut self, layout: Layout) -> u16 { fn alloc(&mut self, layout: Layout) -> u16 {
let size = layout.size(); let size = layout.size();
let align = layout.align(); let align = layout.align().max(4);
let mut position = self.end + size_of::<u16>(); // space for skip marker let mut position = self.end + size_of::<u16>(); // space for skip marker
let alignmask = align - 1; let alignmask = align - 1;
@ -66,7 +66,7 @@ impl PoolInner {
let new_end = position + size; let new_end = position + size;
assert!(new_end < self.data.len(), "ShortPointer memory pool exhausted"); assert!(new_end < self.data.len(), "ShortPointer memory pool exhausted");
// using most significant bit as whether it's been freed // 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(); let skip_marker = 0x8000_u16.to_ne_bytes();
self.data[position - 2..position].copy_from_slice(&skip_marker); self.data[position - 2..position].copy_from_slice(&skip_marker);
@ -74,12 +74,19 @@ impl PoolInner {
if self.begin == 0 { if self.begin == 0 {
self.begin = position; 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; self.last_position = position;
position as u16 (position / 4) as u16
} }
fn dealloc(&mut self, sptr: u16) { fn dealloc(&mut self, sptr: u16) {
let mut position = sptr as usize; let mut position = (sptr * 4) as usize;
unsafe { unsafe {
let skip_marker_ptr = self.data.as_mut_ptr().add(position - 2) as *mut u16; let skip_marker_ptr = self.data.as_mut_ptr().add(position - 2) as *mut u16;
*skip_marker_ptr &= 0x7fff; *skip_marker_ptr &= 0x7fff;
@ -89,10 +96,10 @@ impl PoolInner {
while skip_marker & 0x8000 == 0 { while skip_marker & 0x8000 == 0 {
if skip_marker == 0 { if skip_marker == 0 {
// last object, we can reclaim memory back to sptr // last object, we can reclaim memory back to sptr
self.end = sptr as usize; self.end = (sptr * 4) as usize;
break; break;
} else { } else {
position += skip_marker as usize; position += skip_marker as usize * 4;
} }
skip_marker = *(self.data.as_ptr().add(position - 2) as *const u16); skip_marker = *(self.data.as_ptr().add(position - 2) as *const u16);
} }
@ -105,6 +112,8 @@ impl PoolInner {
self.begin = 0; self.begin = 0;
self.end = 0; self.end = 0;
self.last_position = 0; self.last_position = 0;
} else {
// TODO: restore self.last_position linearly from self.begin
} }
} }
} }
@ -132,7 +141,7 @@ impl<T> Drop for ShortPointer<T> {
impl<T> ShortPointer<T> { impl<T> ShortPointer<T> {
fn deref_inner(&self) -> &mut T { fn deref_inner(&self) -> &mut T {
unsafe { 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()
} }
} }