From 8fa0e6da99f0052123bae633c118d6990405dc05 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 30 Apr 2018 16:46:14 -0700 Subject: [PATCH] Fix simplejit's memory size computations. @steffengy noticed that the code to round allocation sizes up to the neareset page size was incorrect. It was masking off the low bits rather than the high bits. Also, while here, add more comments to `Memory`'s implementation. --- lib/simplejit/src/memory.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/simplejit/src/memory.rs b/lib/simplejit/src/memory.rs index 1ea654e924..2158352cc8 100644 --- a/lib/simplejit/src/memory.rs +++ b/lib/simplejit/src/memory.rs @@ -4,12 +4,19 @@ use errno; use libc; use region; +/// Round `size` up to the nearest multiple of `page_size`. +fn round_up_to_page_size(size: usize, page_size: usize) -> usize { + (size + (page_size - 1)) & !(page_size - 1) +} + +/// A simple struct consisting of a pointer and length. struct PtrLen { ptr: *mut u8, len: usize, } impl PtrLen { + /// Create a new empty `PtrLen`. fn new() -> Self { Self { ptr: ptr::null_mut(), @@ -17,9 +24,11 @@ impl PtrLen { } } + /// Create a new `PtrLen` pointing to at least `size` bytes of memory, + /// suitably sized and aligned for memory protection. fn with_size(size: usize) -> Result { let page_size = region::page::size(); - let alloc_size = (size + (page_size - 1)) & (page_size - 1); + let alloc_size = round_up_to_page_size(size, page_size); unsafe { let mut ptr: *mut libc::c_void = mem::uninitialized(); let err = libc::posix_memalign(&mut ptr, page_size, alloc_size); @@ -35,6 +44,8 @@ impl PtrLen { } } +/// JIT memory manager. This manages pages of suitably aligned and +/// accessible memory. pub struct Memory { allocations: Vec, executable: usize, @@ -77,6 +88,7 @@ impl Memory { Ok(self.current.ptr) } + /// Set all memory allocated in this `Memory` up to now as executable. pub fn set_executable(&mut self) { self.finish_current(); @@ -90,6 +102,7 @@ impl Memory { } } + /// Set all memory allocated in this `Memory` up to now as readonly. pub fn set_readonly(&mut self) { self.finish_current(); @@ -106,3 +119,16 @@ impl Memory { } // TODO: Implement Drop to unprotect and deallocate the memory? + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_round_up_to_page_size() { + assert_eq!(round_up_to_page_size(0, 4096), 0); + assert_eq!(round_up_to_page_size(1, 4096), 4096); + assert_eq!(round_up_to_page_size(4096, 4096), 4096); + assert_eq!(round_up_to_page_size(4097, 4096), 8192); + } +}