diff options
Diffstat (limited to 'crates/ra_prof')
-rw-r--r-- | crates/ra_prof/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/ra_prof/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_prof/src/memory_usage.rs | 52 |
3 files changed, 72 insertions, 0 deletions
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index 787e18385..e986019ca 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml | |||
@@ -10,3 +10,9 @@ once_cell = "0.2.0" | |||
10 | itertools = "0.8.0" | 10 | itertools = "0.8.0" |
11 | backtrace = "0.3.28" | 11 | backtrace = "0.3.28" |
12 | cpuprofiler = { version = "0.0.3", optional = true } | 12 | cpuprofiler = { version = "0.0.3", optional = true } |
13 | jemallocator = { version = "0.1.9", optional = true } | ||
14 | jemalloc-ctl = { version = "0.2.0", optional = true } | ||
15 | |||
16 | |||
17 | [features] | ||
18 | jemalloc = [ "jemallocator", "jemalloc-ctl" ] | ||
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 1e8d780ab..6f7918745 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | mod memory_usage; | ||
2 | |||
1 | use std::{ | 3 | use std::{ |
2 | cell::RefCell, | 4 | cell::RefCell, |
3 | time::{Duration, Instant}, | 5 | time::{Duration, Instant}, |
@@ -11,6 +13,14 @@ use std::{ | |||
11 | use once_cell::sync::Lazy; | 13 | use once_cell::sync::Lazy; |
12 | use itertools::Itertools; | 14 | use itertools::Itertools; |
13 | 15 | ||
16 | pub use crate::memory_usage::{MemoryUsage, Bytes}; | ||
17 | |||
18 | // We use jemalloc mainly to get heap usage statistics, actual performance | ||
19 | // difference is not measures. | ||
20 | #[cfg(feature = "jemalloc")] | ||
21 | #[global_allocator] | ||
22 | static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; | ||
23 | |||
14 | /// Set profiling filter. It specifies descriptions allowed to profile. | 24 | /// Set profiling filter. It specifies descriptions allowed to profile. |
15 | /// This is helpful when call stack has too many nested profiling scopes. | 25 | /// This is helpful when call stack has too many nested profiling scopes. |
16 | /// Additionally filter can specify maximum depth of profiling scopes nesting. | 26 | /// Additionally filter can specify maximum depth of profiling scopes nesting. |
@@ -288,6 +298,10 @@ impl Drop for CpuProfiler { | |||
288 | } | 298 | } |
289 | } | 299 | } |
290 | 300 | ||
301 | pub fn memory_usage() -> MemoryUsage { | ||
302 | MemoryUsage::current() | ||
303 | } | ||
304 | |||
291 | #[cfg(test)] | 305 | #[cfg(test)] |
292 | mod tests { | 306 | mod tests { |
293 | use super::*; | 307 | use super::*; |
diff --git a/crates/ra_prof/src/memory_usage.rs b/crates/ra_prof/src/memory_usage.rs new file mode 100644 index 000000000..2bde8fb5f --- /dev/null +++ b/crates/ra_prof/src/memory_usage.rs | |||
@@ -0,0 +1,52 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | pub struct MemoryUsage { | ||
4 | pub allocated: Bytes, | ||
5 | pub resident: Bytes, | ||
6 | } | ||
7 | |||
8 | impl MemoryUsage { | ||
9 | #[cfg(feature = "jemalloc")] | ||
10 | pub fn current() -> MemoryUsage { | ||
11 | jemalloc_ctl::epoch().unwrap(); | ||
12 | MemoryUsage { | ||
13 | allocated: Bytes(jemalloc_ctl::stats::allocated().unwrap()), | ||
14 | resident: Bytes(jemalloc_ctl::stats::resident().unwrap()), | ||
15 | } | ||
16 | } | ||
17 | |||
18 | #[cfg(not(feature = "jemalloc"))] | ||
19 | pub fn current() -> MemoryUsage { | ||
20 | MemoryUsage { allocated: Bytes(0), resident: Bytes(0) } | ||
21 | } | ||
22 | } | ||
23 | |||
24 | impl fmt::Display for MemoryUsage { | ||
25 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
26 | write!(fmt, "{} allocated {} resident", self.allocated, self.resident,) | ||
27 | } | ||
28 | } | ||
29 | |||
30 | #[derive(Default)] | ||
31 | pub struct Bytes(usize); | ||
32 | |||
33 | impl fmt::Display for Bytes { | ||
34 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
35 | let bytes = self.0; | ||
36 | if bytes < 4096 { | ||
37 | return write!(f, "{} bytes", bytes); | ||
38 | } | ||
39 | let kb = bytes / 1024; | ||
40 | if kb < 4096 { | ||
41 | return write!(f, "{}kb", kb); | ||
42 | } | ||
43 | let mb = kb / 1024; | ||
44 | write!(f, "{}mb", mb) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | impl std::ops::AddAssign<usize> for Bytes { | ||
49 | fn add_assign(&mut self, x: usize) { | ||
50 | self.0 += x; | ||
51 | } | ||
52 | } | ||