Repository: paritytech/substrate
File: client/allocator/src/freeing_bump.rs (Rust)

Code before:
			return Err(error("the allocator has been poisoned"))
		}

		let bomb = PoisonBomb { poisoned: &mut self.poisoned };

		Self::observe_memory_size(&mut self.last_observed_memory_size, mem)?;

		let header_ptr = u32::from(ptr)
			.checked_sub(HEADER_SIZE)
			.ok_or_else(|| error("Invalid pointer for deallocation"))?;

		let order = Header::read_from(mem, header_ptr)?
			.into_occupied()
			.ok_or_else(|| error("the allocation points to an empty header"))?;

		// Update the just freed header and knit it back to the free list.
		let prev_head = self.free_lists.replace(order, Link::Ptr(header_ptr));
		Header::Free(prev_head).write_into(mem, header_ptr)?;

		self.stats.bytes_allocated = self
			.stats
			.bytes_allocated
			.checked_sub(order.size() + HEADER_SIZE)
			.ok_or_else(|| error("underflow of the currently allocated bytes count"))?;

		log::trace!("after deallocation: {:?}", self.stats,);

		bomb.disarm();
		Ok(())
	}

	/// Returns the allocation stats for this allocator.
	pub fn stats(&self) -> AllocationStats {
		self.stats.clone()
	}

	/// Increases the `bumper` by `size`.
	///
	/// 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)
		}


Review comment (suggestion):
```suggestion
		log::trace!("after deallocation: {:?}", self.stats);
```

Code after:
			return Err(error("the allocator has been poisoned"))
		}

		let bomb = PoisonBomb { poisoned: &mut self.poisoned };

		Self::observe_memory_size(&mut self.last_observed_memory_size, mem)?;

		let header_ptr = u32::from(ptr)
			.checked_sub(HEADER_SIZE)
			.ok_or_else(|| error("Invalid pointer for deallocation"))?;

		let order = Header::read_from(mem, header_ptr)?
			.into_occupied()
			.ok_or_else(|| error("the allocation points to an empty header"))?;

		// Update the just freed header and knit it back to the free list.
		let prev_head = self.free_lists.replace(order, Link::Ptr(header_ptr));
		Header::Free(prev_head).write_into(mem, header_ptr)?;

		self.stats.bytes_allocated = self
			.stats
			.bytes_allocated
			.checked_sub(order.size() + HEADER_SIZE)
			.ok_or_else(|| error("underflow of the currently allocated bytes count"))?;

		log::trace!("after deallocation: {:?}", self.stats);

		bomb.disarm();
		Ok(())
	}

	/// Returns the allocation stats for this allocator.
	pub fn stats(&self) -> AllocationStats {
		self.stats.clone()
	}

	/// Increases the `bumper` by `size`.
	///
	/// 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)
		}