Allow the allocator to track the heap changes. (#9291)

* Allow the allocator to track the heap changes.

* fix build

* review comments

* Update client/allocator/Cargo.toml

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/allocator/Cargo.toml

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Kian Paimani
2021-07-07 07:32:57 +02:00
committed by GitHub
parent fb9baeb70b
commit 9cd04f3559
3 changed files with 42 additions and 18 deletions
+40 -15
View File
@@ -85,16 +85,7 @@ fn error(msg: &'static str) -> Error {
Error::Other(msg)
}
/// A custom "trace" implementation that is only activated when `feature = std`.
///
/// Uses `wasm-heap` as default target.
macro_rules! trace {
( $( $args:expr ),+ ) => {
sp_std::if_std! {
log::trace!(target: "wasm-heap", $( $args ),+);
}
}
}
const LOG_TARGET: &'static str = "wasm-heap";
// The minimum possible allocation size is chosen to be 8 bytes because in that case we would have
// easier time to provide the guaranteed alignment of 8.
@@ -146,6 +137,7 @@ impl Order {
/// `MIN_POSSIBLE_ALLOCATION <= size <= MAX_POSSIBLE_ALLOCATION`
fn from_size(size: u32) -> Result<Self, Error> {
let clamped_size = if size > MAX_POSSIBLE_ALLOCATION {
log::warn!(target: LOG_TARGET, "going to fail due to allocating {:?}", size);
return Err(Error::RequestedAllocationTooLarge);
} else if size < MIN_POSSIBLE_ALLOCATION {
MIN_POSSIBLE_ALLOCATION
@@ -331,6 +323,19 @@ pub struct FreeingBumpHeapAllocator {
free_lists: FreeLists,
total_size: u32,
poisoned: bool,
max_total_size: u32,
max_bumper: u32,
}
impl Drop for FreeingBumpHeapAllocator {
fn drop(&mut self) {
log::debug!(
target: LOG_TARGET,
"allocator being destroyed, max_total_size {}, max_bumper {}",
self.max_total_size,
self.max_bumper,
)
}
}
impl FreeingBumpHeapAllocator {
@@ -347,6 +352,8 @@ impl FreeingBumpHeapAllocator {
free_lists: FreeLists::new(),
total_size: 0,
poisoned: false,
max_total_size: 0,
max_bumper: aligned_heap_base,
}
}
@@ -404,7 +411,21 @@ impl FreeingBumpHeapAllocator {
Header::Occupied(order).write_into(mem, header_ptr)?;
self.total_size += order.size() + HEADER_SIZE;
trace!("Heap size is {} bytes after allocation", self.total_size);
log::trace!(
target: LOG_TARGET,
"after allocation, total_size = {}, bumper = {}.",
self.total_size,
self.bumper,
);
// update trackers if needed.
if self.total_size > self.max_total_size {
self.max_total_size = self.total_size;
}
if self.bumper > self.max_bumper {
self.max_bumper = self.bumper;
}
bomb.disarm();
Ok(Pointer::new(header_ptr + HEADER_SIZE))
@@ -442,7 +463,11 @@ impl FreeingBumpHeapAllocator {
.total_size
.checked_sub(order.size() + HEADER_SIZE)
.ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?;
trace!("Heap size is {} bytes after deallocation", self.total_size);
log::trace!(
"after deallocation, total_size = {}, bumper = {}.",
self.total_size,
self.bumper,
);
bomb.disarm();
Ok(())
@@ -450,11 +475,11 @@ impl FreeingBumpHeapAllocator {
/// Increases the `bumper` by `size`.
///
/// Returns the `bumper` from before the increase.
/// Returns an `Error::AllocatorOutOfSpace` if the operation
/// would exhaust the heap.
/// Returns the `bumper` from before the increase. Returns an `Error::AllocatorOutOfSpace` if
/// the operation would exhaust the heap.
fn bump(bumper: &mut u32, size: u32, heap_end: u32) -> Result<u32, Error> {
if *bumper + size > heap_end {
log::error!(target: LOG_TARGET, "running out of space with current bumper {}, mem size {}", bumper, heap_end);
return Err(Error::AllocatorOutOfSpace);
}