Track memory usage (#153)
* Track memory usage * Track lowest_used in copy, etc. * Extra comment for used_size
This commit is contained in:
parent
617be0198d
commit
e047f508fa
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue