Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiling #478

Closed
wants to merge 3 commits into from
Closed

Profiling #478

Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

ProfilerMsg ==> ProfilerCategory; all enums end in Category; added co…

…nst NUM_BUCKETS; other minor changes
  • Loading branch information
Tim Kuehn
Tim Kuehn committed May 24, 2013
commit 089b1fc0c7cbb848b50664df15ed1cc7aacb1f80
@@ -47,7 +47,7 @@ pub impl FontList {
// changed. Does OSX have a notification for this event?
//
// Should font families with entries be invalidated/refreshed too?
do profile(time::GfxRegenFontFF, self.prof_chan.clone()) {
do profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone()) {
self.family_map = self.handle.get_available_families();
}
}
@@ -38,7 +38,7 @@ pub fn render_layers(layer_ref: *RenderLayer,
let mut new_buffer_ports = ~[];

// Divide up the layer into tiles.
do time::profile(time::RenderingPrepBuff, prof_chan.clone()) {
do time::profile(time::RenderingPrepBuffCategory, prof_chan.clone()) {
let layer: &RenderLayer = unsafe { cast::transmute(layer_ref) };
let mut y = 0;
while y < layer.size.height {
@@ -128,7 +128,7 @@ pub fn render_layers(layer_ref: *RenderLayer,
}

let mut new_buffers = ~[];
do time::profile(time::RenderingWaitSubtasks, prof_chan.clone()) {
do time::profile(time::RenderingWaitSubtasksCategory, prof_chan.clone()) {
for new_buffer_ports.each |new_buffer_port| {
new_buffers.push(new_buffer_port.recv());
}
@@ -123,7 +123,7 @@ impl<C: Compositor + Owned> Renderer<C> {

debug!("renderer: rendering");

do profile(time::Rendering, self.prof_chan.clone()) {
do profile(time::RenderingCategory, self.prof_chan.clone()) {
let layer_buffer_set_channel = layer_buffer_set_channel_cell.take();

let layer_buffer_set = do render_layers(&render_layer, &self.opts, self.prof_chan.clone())
@@ -8,23 +8,24 @@ use core::cell::Cell;
use core::comm::{Port, SharedChan};
use core::os::getenv;

pub enum ProfilerMsg {
Compositing,
LayoutPerform,
LayoutQuery,
LayoutAuxInit,
LayoutSelectorMatch,
LayoutTreeBuilder,
LayoutMain,
LayoutDispListBuild,
GfxRegenFontFF,
RenderingPrepBuff,
RenderingWaitSubtasks,
Rendering,
pub enum ProfilerCategory {
CompositingCategory,
LayoutPerformCategory,
LayoutQueryCategory,
LayoutAuxInitCategory,
LayoutSelectorMatchCategory,
LayoutTreeBuilderCategory,
LayoutMainCategory,
LayoutDispListBuildCategory,
GfxRegenAvailableFontsCategory,
RenderingPrepBuffCategory,
RenderingWaitSubtasksCategory,
RenderingCategory,
}
static NUM_BUCKETS: uint = 12;

pub type ProfilerChan = SharedChan<(ProfilerMsg, uint)>;
pub type ProfilerPort = Port<(ProfilerMsg, uint)>;
pub type ProfilerChan = SharedChan<(ProfilerCategory, uint)>;
pub type ProfilerPort = Port<(ProfilerCategory, uint)>;
pub struct ProfilerTask {
chan: ProfilerChan,
}
@@ -48,15 +49,17 @@ impl ProfilerTask {

pub struct ProfilerContext {
port: ProfilerPort,
buckets: [~[uint], ..12],
buckets: [~[uint], ..NUM_BUCKETS],
verbose: Option<~str>,
mut last_print: u64,
}

impl ProfilerContext {
pub fn new(port: ProfilerPort) -> ProfilerContext {
ProfilerContext {
port: port,
buckets: [~[], ..12],
buckets: [~[], ..NUM_BUCKETS],
verbose: getenv("SERVO_PROFILER"),
last_print: 0,
}
}
@@ -68,54 +71,51 @@ impl ProfilerContext {
}
}

priv fn handle_msg(&mut self, msg: (ProfilerMsg, uint)) {
priv fn handle_msg(&mut self, msg: (ProfilerCategory, uint)) {
let (prof_msg, t) = msg;
self.buckets[prof_msg as uint].push(t);
let verbose = getenv("SERVO_PROFILER");
match verbose {
Some(~"1") => {
let cur_time = precise_time_ns() / 1000000000u64;
if cur_time - self.last_print > 5 {
self.last_print = cur_time;
let mut i = 0;
for self.buckets.each |bucket| {
let prof_msg = match i {
0 => Compositing,
1 => LayoutPerform,
2 => LayoutQuery,
3 => LayoutAuxInit,
4 => LayoutSelectorMatch,
5 => LayoutTreeBuilder,
6 => LayoutMain,
7 => LayoutDispListBuild,
8 => GfxRegenFontFF,
9 => RenderingPrepBuff,
10 => RenderingWaitSubtasks,
11 => Rendering,
_ => fail!()
};
io::println(fmt!("%?: %f", prof_msg,
(bucket.foldl(0 as uint, |a, b| a + *b) as float) /
(bucket.len() as float)));
i += 1;
}
if self.verbose.is_some() {
let cur_time = precise_time_ns() / 1000000000u64;
if cur_time - self.last_print > 5 {
self.last_print = cur_time;
let mut i = 0;
for self.buckets.each |bucket| {
let prof_msg = match i {
0 => CompositingCategory,
1 => LayoutPerformCategory,
2 => LayoutQueryCategory,
3 => LayoutAuxInitCategory,
4 => LayoutSelectorMatchCategory,
5 => LayoutTreeBuilderCategory,
6 => LayoutMainCategory,
7 => LayoutDispListBuildCategory,
8 => GfxRegenAvailableFontsCategory,
9 => RenderingPrepBuffCategory,
10 => RenderingWaitSubtasksCategory,
11 => RenderingCategory,
_ => fail!()
};
io::println(fmt!("%?: %f", prof_msg,
(bucket.foldl(0 as uint, |a, b| a + *b) as float) /
(bucket.len() as float)));
i += 1;
}
io::println("");
}
_ => ()
}

}
}

pub fn profile<T>(msg: ProfilerMsg,
pub fn profile<T>(cat: ProfilerCategory,
prof_chan: ProfilerChan,
callback: &fn() -> T)
-> T {
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
let ms = ((end_time - start_time) / 1000000u64) as uint;
prof_chan.send((msg, ms));
prof_chan.send((cat, ms));
return val;
}

@@ -190,7 +190,7 @@ fn run_main_loop(po: Port<Msg>, script_chan: SharedChan<ScriptMsg>, opts: &Opts,
};

do window.set_composite_callback {
do profile(time::Compositing, prof_chan.clone()) {
do profile(time::CompositingCategory, prof_chan.clone()) {
debug!("compositor: compositing");
// Adjust the layer dimensions as necessary to correspond to the size of the window.
scene.size = window.size();
@@ -153,14 +153,14 @@ impl Layout {
BuildMsg(data) => {
let data = Cell(data);

do profile(time::LayoutPerform, self.prof_chan.clone()) {
do profile(time::LayoutPerformCategory, self.prof_chan.clone()) {
self.handle_build(data.take());
}

}
QueryMsg(query, chan) => {
let chan = Cell(chan);
do profile(time::LayoutQuery, self.prof_chan.clone()) {
do profile(time::LayoutQueryCategory, self.prof_chan.clone()) {
self.handle_query(query, chan.take())
}
}
@@ -207,22 +207,23 @@ impl Layout {
// Initialize layout data for each node.
//
// FIXME: This is inefficient. We don't need an entire traversal to do this!
do profile(time::LayoutAuxInit, self.prof_chan.clone()) {
do profile(time::LayoutAuxInitCategory, self.prof_chan.clone()) {
node.initialize_style_for_subtree(&mut self.layout_refs);
}

// Perform CSS selector matching if necessary.
match data.damage {
NoDamage | ReflowDamage => {}
MatchSelectorsDamage => {
do profile(time::LayoutSelectorMatch, self.prof_chan.clone()) {
do profile(time::LayoutSelectorMatchCategory, self.prof_chan.clone()) {
node.restyle_subtree(self.css_select_ctx);
}
}
}

// Construct the flow tree.
let layout_root: FlowContext = do profile(time::LayoutTreeBuilder, self.prof_chan.clone()) {
let layout_root: FlowContext = do profile(time::LayoutTreeBuilderCategory,
self.prof_chan.clone()) {
let mut builder = LayoutTreeBuilder::new();
let layout_root: FlowContext = match builder.construct_trees(&layout_ctx, *node) {
Ok(root) => root,
@@ -237,7 +238,7 @@ impl Layout {

// Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes.
do profile(time::LayoutMain, self.prof_chan.clone()) {
do profile(time::LayoutMainCategory, self.prof_chan.clone()) {
for layout_root.traverse_postorder |flow| {
flow.bubble_widths(&mut layout_ctx);
};
@@ -250,7 +251,7 @@ impl Layout {
}

// Build the display list, and send it to the renderer.
do profile(time::LayoutDispListBuild, self.prof_chan.clone()) {
do profile(time::LayoutDispListBuildCategory, self.prof_chan.clone()) {
let builder = DisplayListBuilder {
ctx: &layout_ctx,
};
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.