mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-25 04:45:42 +00:00
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:
@@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
sp-std = { version = "3.0.0", path = "../../primitives/std", default-features = false }
|
sp-std = { version = "3.0.0", path = "../../primitives/std", default-features = false }
|
||||||
sp-core = { version = "3.0.0", path = "../../primitives/core", default-features = false }
|
sp-core = { version = "3.0.0", path = "../../primitives/core", default-features = false }
|
||||||
sp-wasm-interface = { version = "3.0.0", path = "../../primitives/wasm-interface", default-features = false }
|
sp-wasm-interface = { version = "3.0.0", path = "../../primitives/wasm-interface", default-features = false }
|
||||||
log = { version = "0.4.11", optional = true }
|
log = "0.4.11"
|
||||||
thiserror = { version = "1.0.21" }
|
thiserror = { version = "1.0.21" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@@ -26,5 +26,4 @@ std = [
|
|||||||
"sp-std/std",
|
"sp-std/std",
|
||||||
"sp-core/std",
|
"sp-core/std",
|
||||||
"sp-wasm-interface/std",
|
"sp-wasm-interface/std",
|
||||||
"log",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -85,16 +85,7 @@ fn error(msg: &'static str) -> Error {
|
|||||||
Error::Other(msg)
|
Error::Other(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A custom "trace" implementation that is only activated when `feature = std`.
|
const LOG_TARGET: &'static str = "wasm-heap";
|
||||||
///
|
|
||||||
/// Uses `wasm-heap` as default target.
|
|
||||||
macro_rules! trace {
|
|
||||||
( $( $args:expr ),+ ) => {
|
|
||||||
sp_std::if_std! {
|
|
||||||
log::trace!(target: "wasm-heap", $( $args ),+);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The minimum possible allocation size is chosen to be 8 bytes because in that case we would have
|
// 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.
|
// easier time to provide the guaranteed alignment of 8.
|
||||||
@@ -146,6 +137,7 @@ impl Order {
|
|||||||
/// `MIN_POSSIBLE_ALLOCATION <= size <= MAX_POSSIBLE_ALLOCATION`
|
/// `MIN_POSSIBLE_ALLOCATION <= size <= MAX_POSSIBLE_ALLOCATION`
|
||||||
fn from_size(size: u32) -> Result<Self, Error> {
|
fn from_size(size: u32) -> Result<Self, Error> {
|
||||||
let clamped_size = if size > MAX_POSSIBLE_ALLOCATION {
|
let clamped_size = if size > MAX_POSSIBLE_ALLOCATION {
|
||||||
|
log::warn!(target: LOG_TARGET, "going to fail due to allocating {:?}", size);
|
||||||
return Err(Error::RequestedAllocationTooLarge);
|
return Err(Error::RequestedAllocationTooLarge);
|
||||||
} else if size < MIN_POSSIBLE_ALLOCATION {
|
} else if size < MIN_POSSIBLE_ALLOCATION {
|
||||||
MIN_POSSIBLE_ALLOCATION
|
MIN_POSSIBLE_ALLOCATION
|
||||||
@@ -331,6 +323,19 @@ pub struct FreeingBumpHeapAllocator {
|
|||||||
free_lists: FreeLists,
|
free_lists: FreeLists,
|
||||||
total_size: u32,
|
total_size: u32,
|
||||||
poisoned: bool,
|
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 {
|
impl FreeingBumpHeapAllocator {
|
||||||
@@ -347,6 +352,8 @@ impl FreeingBumpHeapAllocator {
|
|||||||
free_lists: FreeLists::new(),
|
free_lists: FreeLists::new(),
|
||||||
total_size: 0,
|
total_size: 0,
|
||||||
poisoned: false,
|
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)?;
|
Header::Occupied(order).write_into(mem, header_ptr)?;
|
||||||
|
|
||||||
self.total_size += order.size() + HEADER_SIZE;
|
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();
|
bomb.disarm();
|
||||||
Ok(Pointer::new(header_ptr + HEADER_SIZE))
|
Ok(Pointer::new(header_ptr + HEADER_SIZE))
|
||||||
@@ -442,7 +463,11 @@ impl FreeingBumpHeapAllocator {
|
|||||||
.total_size
|
.total_size
|
||||||
.checked_sub(order.size() + HEADER_SIZE)
|
.checked_sub(order.size() + HEADER_SIZE)
|
||||||
.ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?;
|
.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();
|
bomb.disarm();
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -450,11 +475,11 @@ impl FreeingBumpHeapAllocator {
|
|||||||
|
|
||||||
/// Increases the `bumper` by `size`.
|
/// Increases the `bumper` by `size`.
|
||||||
///
|
///
|
||||||
/// Returns the `bumper` from before the increase.
|
/// Returns the `bumper` from before the increase. Returns an `Error::AllocatorOutOfSpace` if
|
||||||
/// Returns an `Error::AllocatorOutOfSpace` if the operation
|
/// the operation would exhaust the heap.
|
||||||
/// would exhaust the heap.
|
|
||||||
fn bump(bumper: &mut u32, size: u32, heap_end: u32) -> Result<u32, Error> {
|
fn bump(bumper: &mut u32, size: u32, heap_end: u32) -> Result<u32, Error> {
|
||||||
if *bumper + size > heap_end {
|
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);
|
return Err(Error::AllocatorOutOfSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ fn get_table(instance: &Instance) -> Option<Table> {
|
|||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Functions realted to memory.
|
/// Functions related to memory.
|
||||||
impl InstanceWrapper {
|
impl InstanceWrapper {
|
||||||
/// Read data from a slice of memory into a destination buffer.
|
/// Read data from a slice of memory into a destination buffer.
|
||||||
///
|
///
|
||||||
|
|||||||
Reference in New Issue
Block a user