Track memory usage (#153)

* Track memory usage

* Track lowest_used in copy, etc.

* Extra comment for used_size
This commit is contained in:
Arkadiy Paronyan 2019-01-03 00:13:21 +03:00 committed by Sergei Pepyakin
parent 617be0198d
commit e047f508fa
1 changed files with 41 additions and 0 deletions

View File

@ -58,6 +58,7 @@ pub struct MemoryInstance {
initial: Pages, initial: Pages,
current_size: Cell<usize>, current_size: Cell<usize>,
maximum: Option<Pages>, maximum: Option<Pages>,
lowest_used: Cell<u32>,
} }
impl fmt::Debug for MemoryInstance { impl fmt::Debug for MemoryInstance {
@ -127,6 +128,7 @@ impl MemoryInstance {
initial: initial, initial: initial,
current_size: Cell::new(initial_size.0), current_size: Cell::new(initial_size.0),
maximum: maximum, maximum: maximum,
lowest_used: Cell::new(u32::max_value()),
} }
} }
@ -148,6 +150,16 @@ impl MemoryInstance {
self.maximum self.maximum
} }
/// Returns lowest offset ever written or `u32::max_value()` if none.
pub fn lowest_used(&self) -> u32 {
self.lowest_used.get()
}
/// Resets tracked lowest offset.
pub fn reset_lowest_used(&self, addr: u32) {
self.lowest_used.set(addr)
}
/// Returns current linear memory size. /// Returns current linear memory size.
/// ///
/// Maximum memory size cannot exceed `65536` pages or 4GiB. /// Maximum memory size cannot exceed `65536` pages or 4GiB.
@ -171,6 +183,12 @@ impl MemoryInstance {
Bytes(self.current_size.get()).round_up_to() Bytes(self.current_size.get()).round_up_to()
} }
/// Returns current used memory size in bytes.
/// This is the highest memory address that had been written to.
pub fn used_size(&self) -> Bytes {
Bytes(self.buffer.borrow().len())
}
/// Get value from memory at given offset. /// Get value from memory at given offset.
pub fn get_value<T: LittleEndianConvert>(&self, offset: u32) -> Result<T, Error> { pub fn get_value<T: LittleEndianConvert>(&self, offset: u32) -> Result<T, Error> {
let mut buffer = self.buffer.borrow_mut(); let mut buffer = self.buffer.borrow_mut();
@ -213,6 +231,9 @@ impl MemoryInstance {
.checked_region(&mut buffer, offset as usize, value.len())? .checked_region(&mut buffer, offset as usize, value.len())?
.range(); .range();
if offset < self.lowest_used.get() {
self.lowest_used.set(offset);
}
buffer[range].copy_from_slice(value); buffer[range].copy_from_slice(value);
Ok(()) Ok(())
@ -224,6 +245,9 @@ impl MemoryInstance {
let range = self let range = self
.checked_region(&mut buffer, offset as usize, ::core::mem::size_of::<T>())? .checked_region(&mut buffer, offset as usize, ::core::mem::size_of::<T>())?
.range(); .range();
if offset < self.lowest_used.get() {
self.lowest_used.set(offset);
}
value.into_little_endian(&mut buffer[range]); value.into_little_endian(&mut buffer[range]);
Ok(()) Ok(())
} }
@ -368,6 +392,10 @@ impl MemoryInstance {
let (read_region, write_region) = let (read_region, write_region) =
self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?; self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?;
if dst_offset < self.lowest_used.get() as usize {
self.lowest_used.set(dst_offset as u32);
}
unsafe { unsafe {
::core::ptr::copy( ::core::ptr::copy(
buffer[read_region.range()].as_ptr(), buffer[read_region.range()].as_ptr(),
@ -407,6 +435,10 @@ impl MemoryInstance {
))); )));
} }
if dst_offset < self.lowest_used.get() as usize {
self.lowest_used.set(dst_offset as u32);
}
unsafe { unsafe {
::core::ptr::copy_nonoverlapping( ::core::ptr::copy_nonoverlapping(
buffer[read_region.range()].as_ptr(), buffer[read_region.range()].as_ptr(),
@ -446,6 +478,10 @@ impl MemoryInstance {
.checked_region(&mut dst_buffer, dst_offset, len)? .checked_region(&mut dst_buffer, dst_offset, len)?
.range(); .range();
if dst_offset < dst.lowest_used.get() as usize {
dst.lowest_used.set(dst_offset as u32);
}
dst_buffer[dst_range].copy_from_slice(&src_buffer[src_range]); dst_buffer[dst_range].copy_from_slice(&src_buffer[src_range]);
Ok(()) Ok(())
@ -462,6 +498,11 @@ impl MemoryInstance {
let mut buffer = self.buffer.borrow_mut(); let mut buffer = self.buffer.borrow_mut();
let range = self.checked_region(&mut buffer, offset, len)?.range(); let range = self.checked_region(&mut buffer, offset, len)?.range();
if offset < self.lowest_used.get() as usize {
self.lowest_used.set(offset as u32);
}
for val in &mut buffer[range] { for val in &mut buffer[range] {
*val = new_val *val = new_val
} }