From 640e68bbbd10defc8090d14b94932aa599ef75ef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 27 May 2015 18:57:13 -0700 Subject: [PATCH] Recursively sort memory report sub-trees. This puts the larger sub-trees first. E.g. this: ``` | 1.04 MiB -- url(http://en.wikipedia.org/wiki/Main_Page) | 0.26 MiB -- display-list | 0.78 MiB -- paint-task # new output line | 0.78 MiB -- buffer-map # new output line ``` becomes this: ``` | 1.04 MiB -- url(http://en.wikipedia.org/wiki/Main_Page) | 0.78 MiB -- paint-task # new output line | 0.78 MiB -- buffer-map # new output line | 0.26 MiB -- display-list ``` This matches how Firefox's about:memory works. Now that this is done for all sub-trees, the ad hoc sorting done for Linux segments is no longer necessary, and has been removed. --- components/profile/mem.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/components/profile/mem.rs b/components/profile/mem.rs index 26aff02bb05..79437c2ba17 100644 --- a/components/profile/mem.rs +++ b/components/profile/mem.rs @@ -195,9 +195,9 @@ impl ReportsTree { t.count += 1; } - // Fill in sizes for interior nodes. Should only be done once all the reports have been - // inserted. - fn compute_interior_node_sizes(&mut self) -> usize { + // Fill in sizes for interior nodes and sort sub-trees accordingly. Should only be done once + // all the reports have been inserted. + fn compute_interior_node_sizes_and_sort(&mut self) -> usize { if !self.children.is_empty() { // Interior node. Derive its size from its children. if self.size != 0 { @@ -205,8 +205,10 @@ impl ReportsTree { panic!("one report's path is a sub-path of another report's path"); } for child in self.children.iter_mut() { - self.size += child.compute_interior_node_sizes(); + self.size += child.compute_interior_node_sizes_and_sort(); } + // Now that child sizes have been computed, we can sort the children. + self.children.sort_by(|t1, t2| t2.size.cmp(&t1.size)); } self.size } @@ -258,9 +260,9 @@ impl ReportsForest { } fn print(&mut self) { - // Fill in sizes of interior nodes. + // Fill in sizes of interior nodes, and recursively sort the sub-trees. for (_, tree) in self.trees.iter_mut() { - tree.compute_interior_node_sizes(); + tree.compute_interior_node_sizes_and_sort(); } // Put the trees into a sorted vector. Primary sort: degenerate trees (those containing a @@ -351,7 +353,6 @@ mod system_reporter { } } - #[cfg(target_os="linux")] extern { fn mallinfo() -> struct_mallinfo; @@ -572,13 +573,10 @@ mod system_reporter { } } - let mut segs: Vec<(String, usize)> = seg_map.into_iter().collect(); - - // Note that the sum of all these segments' RSS values differs from the "resident" measurement - // obtained via /proc//statm in get_resident(). It's unclear why this difference occurs; - // for some processes the measurements match, but for Servo they do not. - segs.sort_by(|&(_, rss1), &(_, rss2)| rss2.cmp(&rss1)); - + // Note that the sum of all these segments' RSS values differs from the "resident" + // measurement obtained via /proc//statm in get_resident(). It's unclear why this + // difference occurs; for some processes the measurements match, but for Servo they do not. + let segs: Vec<(String, usize)> = seg_map.into_iter().collect(); segs }