From 7713e141b714adc6416994b7783b51f56996a7ba Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sat, 27 Jun 2015 18:37:33 -0700 Subject: [PATCH] Report memory use in time-passes Reports the resident set size after each pass (linux-only). --- src/librustc/lib.rs | 1 + src/librustc/util/common.rs | 40 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2cec42b76bc..e4e7459f8c6 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -62,6 +62,7 @@ #![feature(vec_push_all)] #![feature(wrapping)] #![feature(cell_extras)] +#![feature(page_size)] #![cfg_attr(test, feature(test))] #![allow(trivial_casts)] diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 8d5357fa6e4..162bf6ed9a9 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -59,14 +59,50 @@ pub fn time(do_it: bool, what: &str, u: U, f: F) -> T where const NANOS_PER_SEC: f64 = 1_000_000_000.0; let secs = dur.secs() as f64; let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC; - println!("{}time: {:.3} \t{}", repeat(" ").take(old).collect::(), - secs, what); + + let mem_string = match get_resident() { + Some(n) => { + let mb = n as f64 / 1_000_000.0; + format!("; rss: {}MB", mb.round() as usize) + } + None => "".to_owned(), + }; + println!("{}time: {:.3}{}\t{}", repeat(" ").take(old).collect::(), + secs, mem_string, what); DEPTH.with(|slot| slot.set(old)); rv } +// Memory reporting +fn get_resident() -> Option { + if cfg!(unix) { + get_proc_self_statm_field(1) + } else { + None + } +} + +// Like std::macros::try!, but for Option<>. +macro_rules! option_try( + ($e:expr) => (match $e { Some(e) => e, None => return None }) +); + +fn get_proc_self_statm_field(field: usize) -> Option { + use std::fs::File; + use std::io::Read; + + assert!(cfg!(unix)); + + let mut f = option_try!(File::open("/proc/self/statm").ok()); + let mut contents = String::new(); + option_try!(f.read_to_string(&mut contents).ok()); + let s = option_try!(contents.split_whitespace().nth(field)); + let npages = option_try!(s.parse::().ok()); + Some(npages * ::std::env::page_size()) +} + pub fn indent(op: F) -> R where R: Debug, F: FnOnce() -> R,