Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created December 10, 2018 14:41
Show Gist options
  • Save rust-play/20ba623ec68897f98746091e0c7cc69a to your computer and use it in GitHub Desktop.
Save rust-play/20ba623ec68897f98746091e0c7cc69a to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
use std::alloc::{GlobalAlloc, System, Layout};
use std::sync::atomic::{AtomicIsize, Ordering};
struct AllocationTracker {
mem: AtomicIsize
}
impl AllocationTracker {
const fn new() -> Self {
AllocationTracker {
mem: AtomicIsize::new(0)
}
}
fn current_mem(&self) -> isize {
self.mem.load(Ordering::SeqCst)
}
}
unsafe impl GlobalAlloc for AllocationTracker {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
self.mem.fetch_add(layout.size() as isize, Ordering::SeqCst);
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
self.mem.fetch_sub(layout.size() as isize, Ordering::SeqCst);
System.dealloc(ptr, layout)
}
}
#[global_allocator]
static GLOBAL: AllocationTracker = AllocationTracker::new();
struct ScopeTracker<'a> {
at_start: isize,
name: &'a str,
file: &'static str,
line: u32,
}
impl<'a> ScopeTracker<'a> {
fn new(name: &'a str, file: &'static str, line: u32) -> Self {
Self {
at_start: GLOBAL.current_mem(),
name,
file,
line,
}
}
}
impl Drop for ScopeTracker<'_> {
fn drop(&mut self) {
let old = self.at_start;
let new = GLOBAL.current_mem();
if old != new {
if self.name == "" {
println!("{}:{}: {} bytes escape scope", self.file, self.line, new - old);
} else {
println!("{}:{} '{}': {} bytes escape scope", self.file, self.line, self.name, new - old);
}
}
}
}
macro_rules! mem_guard {
() => (
mem_guard!("")
);
($e:expr) => (
let _guard = ScopeTracker::new($e, file!(), line!());
)
}
fn main() {
for i in 0..10 {
mem_guard!();
let x = vec![0; 1024];
if i == 2 {
::std::mem::forget(x);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment