servo: Merge #5912 - Add a `profile_traits` crate to reduce compile times (from nnethercote:profile_traits); r=Manishearth
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 30 Apr 2015 20:02:33 -0500
changeset 382937 3ac3db2cf2a3f01a80afe13dd85e764f5b25a33a
parent 382936 ac1a2d43bd8ea4eb5ea4103f2a039ec003519cf0
child 382938 83c7ed4a1f92a1d55f365ee835d3cc466357e8e2
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersManishearth
servo: Merge #5912 - Add a `profile_traits` crate to reduce compile times (from nnethercote:profile_traits); r=Manishearth A rebuild after touching components/profile/mem.rs now takes 48 seconds (and only rebuilds `profile` and `servo`) which is much lower than it used to be. In comparison, a rebuild after touching components/profile_traits/mem.rs takes 294 seconds and rebuilds many more crates. This change also removes some unnecessary crate dependencies in `net` and `net_traits`. Source-Repo: https://github.com/servo/servo Source-Revision: 77f653da2c4120ea7ac1a946d97fc70059d513d4
servo/components/compositing/Cargo.toml
servo/components/compositing/compositor.rs
servo/components/compositing/compositor_task.rs
servo/components/compositing/constellation.rs
servo/components/compositing/headless.rs
servo/components/compositing/lib.rs
servo/components/compositing/pipeline.rs
servo/components/gfx/Cargo.toml
servo/components/gfx/lib.rs
servo/components/gfx/paint_task.rs
servo/components/layout/Cargo.toml
servo/components/layout/layout_task.rs
servo/components/layout/lib.rs
servo/components/layout/parallel.rs
servo/components/layout_traits/Cargo.toml
servo/components/layout_traits/lib.rs
servo/components/net/Cargo.toml
servo/components/net/lib.rs
servo/components/net_traits/Cargo.toml
servo/components/net_traits/lib.rs
servo/components/profile/Cargo.toml
servo/components/profile/lib.rs
servo/components/profile/mem.rs
servo/components/profile/time.rs
servo/components/profile_traits/Cargo.toml
servo/components/profile_traits/lib.rs
servo/components/profile_traits/mem.rs
servo/components/profile_traits/time.rs
servo/components/script/Cargo.toml
servo/components/script/layout_interface.rs
servo/components/script/lib.rs
servo/components/servo/Cargo.lock
servo/components/servo/Cargo.toml
servo/components/servo/lib.rs
servo/ports/cef/Cargo.lock
servo/tests/unit/net/Cargo.toml
servo/tests/unit/net/lib.rs
--- a/servo/components/compositing/Cargo.toml
+++ b/servo/components/compositing/Cargo.toml
@@ -17,18 +17,18 @@ path = "../layout_traits"
 path = "../script_traits"
 
 [dependencies.msg]
 path = "../msg"
 
 [dependencies.net]
 path = "../net"
 
-[dependencies.profile]
-path = "../profile"
+[dependencies.profile_traits]
+path = "../profile_traits"
 
 [dependencies.net_traits]
 path = "../net_traits"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies.webdriver_traits]
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -27,18 +27,18 @@ use layers::rendergl;
 use layers::scene::Scene;
 use msg::compositor_msg::{Epoch, LayerId};
 use msg::compositor_msg::{ReadyState, PaintState, ScrollPolicy};
 use msg::constellation_msg::Msg as ConstellationMsg;
 use msg::constellation_msg::{ConstellationChan, NavigationDirection};
 use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData};
 use msg::constellation_msg::{PipelineId, WindowSizeData};
 use png;
-use profile::mem;
-use profile::time::{self, ProfilerCategory, profile};
+use profile_traits::mem;
+use profile_traits::time::{self, ProfilerCategory, profile};
 use script_traits::{ConstellationControlMsg, ScriptControlChan};
 use std::cmp;
 use std::collections::HashMap;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::mem as std_mem;
 use std::num::Float;
 use std::rc::Rc;
 use std::slice::bytes::copy_memory;
--- a/servo/components/compositing/compositor_task.rs
+++ b/servo/components/compositing/compositor_task.rs
@@ -16,18 +16,18 @@ use geom::point::Point2D;
 use geom::rect::Rect;
 use geom::size::Size2D;
 use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
 use layers::layers::LayerBufferSet;
 use msg::compositor_msg::{Epoch, LayerId, LayerMetadata, ReadyState};
 use msg::compositor_msg::{PaintListener, PaintState, ScriptListener, ScrollPolicy};
 use msg::constellation_msg::{ConstellationChan, PipelineId};
 use msg::constellation_msg::{Key, KeyState, KeyModifiers};
-use profile::mem;
-use profile::time;
+use profile_traits::mem;
+use profile_traits::time;
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::fmt::{Error, Formatter, Debug};
 use std::rc::Rc;
 use url::Url;
 use util::cursor::Cursor;
 
 /// Sends messages to the compositor. This is a trait supplied by the port because the method used
 /// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
--- a/servo/components/compositing/constellation.rs
+++ b/servo/components/compositing/constellation.rs
@@ -18,18 +18,18 @@ use msg::constellation_msg::Msg as Const
 use msg::constellation_msg::{FrameId, PipelineExitType, PipelineId};
 use msg::constellation_msg::{IFrameSandboxState, MozBrowserEvent, NavigationDirection};
 use msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData};
 use msg::constellation_msg::{SubpageId, WindowSizeData};
 use msg::constellation_msg::{self, ConstellationChan, Failure};
 use net_traits::{self, ResourceTask};
 use net_traits::image_cache_task::ImageCacheTask;
 use net_traits::storage_task::{StorageTask, StorageTaskMsg};
-use profile::mem;
-use profile::time;
+use profile_traits::mem;
+use profile_traits::time;
 use script_traits::{CompositorEvent, ConstellationControlMsg};
 use script_traits::{ScriptControlChan, ScriptTaskFactory};
 use std::borrow::ToOwned;
 use std::collections::HashMap;
 use std::io::{self, Write};
 use std::marker::PhantomData;
 use std::mem::replace;
 use std::sync::mpsc::{Sender, Receiver, channel};
--- a/servo/components/compositing/headless.rs
+++ b/servo/components/compositing/headless.rs
@@ -4,18 +4,18 @@
 
 use compositor_task::{CompositorEventListener, CompositorReceiver, Msg};
 use windowing::WindowEvent;
 
 use geom::scale_factor::ScaleFactor;
 use geom::size::TypedSize2D;
 use msg::constellation_msg::Msg as ConstellationMsg;
 use msg::constellation_msg::{ConstellationChan, WindowSizeData};
-use profile::mem;
-use profile::time;
+use profile_traits::mem;
+use profile_traits::time;
 
 /// Starts the compositor, which listens for messages on the specified port.
 ///
 /// This is the null compositor which doesn't draw anything to the screen.
 /// It's intended for headless testing.
 pub struct NullCompositor {
     /// The port on which we receive messages.
     pub port: Box<CompositorReceiver>,
--- a/servo/components/compositing/lib.rs
+++ b/servo/components/compositing/lib.rs
@@ -17,17 +17,17 @@ extern crate devtools_traits;
 extern crate geom;
 extern crate gfx;
 extern crate layers;
 extern crate layout_traits;
 extern crate png;
 extern crate script_traits;
 extern crate msg;
 extern crate net;
-extern crate profile;
+extern crate profile_traits;
 extern crate net_traits;
 #[macro_use]
 extern crate util;
 extern crate gleam;
 extern crate webdriver_traits;
 extern crate clipboard;
 
 extern crate libc;
--- a/servo/components/compositing/pipeline.rs
+++ b/servo/components/compositing/pipeline.rs
@@ -11,18 +11,18 @@ use devtools_traits::DevtoolsControlChan
 use geom::rect::{TypedRect};
 use geom::scale_factor::ScaleFactor;
 use gfx::paint_task::Msg as PaintMsg;
 use gfx::paint_task::{PaintChan, PaintTask};
 use gfx::font_cache_task::FontCacheTask;
 use layers::geometry::DevicePixel;
 use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
 use msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType, MozBrowserEvent};
-use profile::mem;
-use profile::time;
+use profile_traits::mem;
+use profile_traits::time;
 use net_traits::ResourceTask;
 use net_traits::image_cache_task::ImageCacheTask;
 use net_traits::storage_task::StorageTask;
 use std::sync::mpsc::{Receiver, channel};
 use url::Url;
 use util::geometry::{PagePx, ViewportPx};
 use util::opts;
 
--- a/servo/components/gfx/Cargo.toml
+++ b/servo/components/gfx/Cargo.toml
@@ -15,18 +15,18 @@ path = "../plugins"
 path = "../net_traits"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies.msg]
 path = "../msg"
 
-[dependencies.profile]
-path = "../profile"
+[dependencies.profile_traits]
+path = "../profile_traits"
 
 [dependencies.style]
 path = "../style"
 
 [dependencies.azure]
 git = "https://github.com/servo/rust-azure"
 
 [dependencies.geom]
--- a/servo/components/gfx/lib.rs
+++ b/servo/components/gfx/lib.rs
@@ -21,17 +21,17 @@ extern crate log;
 extern crate azure;
 #[macro_use] extern crate bitflags;
 extern crate collections;
 extern crate geom;
 extern crate layers;
 extern crate libc;
 extern crate stb_image;
 extern crate png;
-extern crate profile;
+extern crate profile_traits;
 extern crate script_traits;
 extern crate "rustc-serialize" as rustc_serialize;
 extern crate unicode;
 extern crate net_traits;
 #[macro_use]
 extern crate util;
 extern crate msg;
 extern crate string_cache;
--- a/servo/components/gfx/paint_task.rs
+++ b/servo/components/gfx/paint_task.rs
@@ -20,17 +20,17 @@ use layers::platform::surface::{NativeGr
 use layers::platform::surface::NativeSurface;
 use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet};
 use layers;
 use msg::compositor_msg::{Epoch, PaintState, LayerId};
 use msg::compositor_msg::{LayerMetadata, PaintListener, ScrollPolicy};
 use msg::constellation_msg::Msg as ConstellationMsg;
 use msg::constellation_msg::{ConstellationChan, Failure, PipelineId};
 use msg::constellation_msg::PipelineExitType;
-use profile::time::{self, profile};
+use profile_traits::time::{self, profile};
 use skia::SkiaGrGLNativeContextRef;
 use std::borrow::ToOwned;
 use std::mem;
 use std::sync::Arc;
 use std::sync::mpsc::{Receiver, Sender, channel};
 use util::geometry::{Au, ZERO_POINT};
 use util::opts;
 use util::smallvec::SmallVec;
--- a/servo/components/layout/Cargo.toml
+++ b/servo/components/layout/Cargo.toml
@@ -32,18 +32,18 @@ path = "../script_traits"
 path = "../style"
 
 [dependencies.plugins]
 path = "../plugins"
 
 [dependencies.net_traits]
 path = "../net_traits"
 
-[dependencies.profile]
-path = "../profile"
+[dependencies.profile_traits]
+path = "../profile_traits"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies.cssparser]
 git = "https://github.com/servo/rust-cssparser"
 
 [dependencies.selectors]
--- a/servo/components/layout/layout_task.rs
+++ b/servo/components/layout/layout_task.rs
@@ -37,19 +37,19 @@ use gfx::display_list::{StackingContext}
 use gfx::font_cache_task::FontCacheTask;
 use gfx::paint_task::Msg as PaintMsg;
 use gfx::paint_task::{PaintChan, PaintLayer};
 use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
 use log;
 use msg::compositor_msg::ScrollPolicy;
 use msg::constellation_msg::Msg as ConstellationMsg;
 use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId};
-use profile::mem::{self, Report, ReportsChan};
-use profile::time::{self, ProfilerMetadata, profile};
-use profile::time::{TimerMetadataFrameType, TimerMetadataReflowType};
+use profile_traits::mem::{self, Report, ReportsChan};
+use profile_traits::time::{self, ProfilerMetadata, profile};
+use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
 use net_traits::{load_bytes_iter, ResourceTask};
 use net_traits::image_cache_task::{ImageCacheTask, ImageCacheResult, ImageCacheChan};
 use script::dom::bindings::js::LayoutJS;
 use script::dom::node::{LayoutData, Node};
 use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse};
 use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC};
 use script::layout_interface::{MouseOverResponse, Msg, Reflow, ReflowGoal, ReflowQueryType};
 use script::layout_interface::{ScriptLayoutChan, ScriptReflow, TrustedNodeAddress};
--- a/servo/components/layout/lib.rs
+++ b/servo/components/layout/lib.rs
@@ -27,17 +27,17 @@ extern crate log;
 #[macro_use]
 extern crate bitflags;
 
 #[macro_use]
 #[no_link]
 extern crate "plugins" as servo_plugins;
 extern crate net_traits;
 #[macro_use]
-extern crate profile;
+extern crate profile_traits;
 
 #[macro_use]
 extern crate util;
 
 extern crate "rustc-serialize" as rustc_serialize;
 extern crate alloc;
 extern crate azure;
 extern crate canvas;
--- a/servo/components/layout/parallel.rs
+++ b/servo/components/layout/parallel.rs
@@ -15,17 +15,17 @@ use flow_ref::FlowRef;
 use data::{LayoutDataAccess, LayoutDataWrapper};
 use traversal::{BubbleISizes, AssignISizes, AssignBSizesAndStoreOverflow};
 use traversal::{ComputeAbsolutePositions, BuildDisplayList};
 use traversal::{RecalcStyleForNode, ConstructFlows};
 use wrapper::{layout_node_to_unsafe_layout_node, layout_node_from_unsafe_layout_node, LayoutNode};
 use wrapper::{PostorderNodeMutTraversal, UnsafeLayoutNode};
 use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
 
-use profile::time::{self, ProfilerMetadata, profile};
+use profile_traits::time::{self, ProfilerMetadata, profile};
 use std::mem;
 use std::ptr;
 use std::sync::atomic::{AtomicIsize, Ordering};
 use util::opts;
 use util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
 
 #[allow(dead_code)]
 fn static_assertion(node: UnsafeLayoutNode) {
--- a/servo/components/layout_traits/Cargo.toml
+++ b/servo/components/layout_traits/Cargo.toml
@@ -14,16 +14,16 @@ path = "../gfx"
 path = "../script_traits"
 
 [dependencies.msg]
 path = "../msg"
 
 [dependencies.net_traits]
 path = "../net_traits"
 
-[dependencies.profile]
-path = "../profile"
+[dependencies.profile_traits]
+path = "../profile_traits"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies]
 url = "0.2.16"
--- a/servo/components/layout_traits/lib.rs
+++ b/servo/components/layout_traits/lib.rs
@@ -1,30 +1,30 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 extern crate gfx;
 extern crate script_traits;
 extern crate msg;
-extern crate profile;
+extern crate profile_traits;
 extern crate net_traits;
 extern crate url;
 extern crate util;
 
 // This module contains traits in layout used generically
 //   in the rest of Servo.
 // The traits are here instead of in layout so
 //   that these modules won't have to depend on layout.
 
 use gfx::font_cache_task::FontCacheTask;
 use gfx::paint_task::PaintChan;
 use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, PipelineExitType};
-use profile::mem;
-use profile::time;
+use profile_traits::mem;
+use profile_traits::time;
 use net_traits::ResourceTask;
 use net_traits::image_cache_task::ImageCacheTask;
 use url::Url;
 use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel};
 use std::sync::mpsc::{Sender, Receiver};
 
 /// Messages sent to the layout task from the constellation
 pub enum LayoutControlMsg {
--- a/servo/components/net/Cargo.toml
+++ b/servo/components/net/Cargo.toml
@@ -2,19 +2,16 @@
 name = "net"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 
 [lib]
 name = "net"
 path = "lib.rs"
 
-[dependencies.profile]
-path = "../profile"
-
 [dependencies.net_traits]
 path = "../net_traits"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies.geom]
 git = "https://github.com/servo/rust-geom"
--- a/servo/components/net/lib.rs
+++ b/servo/components/net/lib.rs
@@ -22,17 +22,16 @@ extern crate "cookie" as cookie_rs;
 extern crate collections;
 extern crate flate2;
 extern crate geom;
 extern crate hyper;
 extern crate png;
 #[macro_use]
 extern crate log;
 extern crate openssl;
-extern crate profile;
 extern crate "rustc-serialize" as rustc_serialize;
 extern crate util;
 extern crate time;
 extern crate url;
 
 extern crate regex;
 
 pub mod about_loader;
--- a/servo/components/net_traits/Cargo.toml
+++ b/servo/components/net_traits/Cargo.toml
@@ -8,19 +8,16 @@ name = "net_traits"
 path = "lib.rs"
 
 [dependencies.geom]
 git = "https://github.com/servo/rust-geom"
 
 [dependencies.png]
 git = "https://github.com/servo/rust-png"
 
-[dependencies.profile]
-path = "../profile"
-
 [dependencies.util]
 path = "../util"
 
 [dependencies.stb_image]
 git = "https://github.com/servo/rust-stb-image"
 
 [dependencies]
 url = "0.2.16"
--- a/servo/components/net_traits/lib.rs
+++ b/servo/components/net_traits/lib.rs
@@ -7,17 +7,16 @@
 #![feature(core)]
 #![feature(rustc_private)]
 
 extern crate geom;
 extern crate hyper;
 #[macro_use]
 extern crate log;
 extern crate png;
-extern crate profile;
 extern crate stb_image;
 extern crate url;
 extern crate util;
 
 use hyper::header::{ContentType, Headers};
 use hyper::http::RawStatus;
 use hyper::method::Method;
 use hyper::mime::{Mime, Attr};
--- a/servo/components/profile/Cargo.toml
+++ b/servo/components/profile/Cargo.toml
@@ -2,19 +2,21 @@
 name = "profile"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 
 [lib]
 name = "profile"
 path = "lib.rs"
 
+[dependencies.profile_traits]
+path = "../profile_traits"
+
 [dependencies.task_info]
 path = "../../support/rust-task_info"
 
 [dependencies.util]
 path = "../util"
 
 [dependencies]
 libc = "*"
 regex = "0.1.14"
 time = "0.1.12"
-url = "0.2.16"
--- a/servo/components/profile/lib.rs
+++ b/servo/components/profile/lib.rs
@@ -11,18 +11,19 @@
 #![feature(rustc_private)]
 #![feature(std_misc)]
 #![cfg_attr(target_os="linux", feature(str_words))]
 
 #[macro_use] extern crate log;
 
 extern crate collections;
 extern crate libc;
+#[macro_use]
+extern crate profile_traits;
 #[cfg(target_os="linux")]
 extern crate regex;
 #[cfg(target_os="macos")]
 extern crate task_info;
 extern crate "time" as std_time;
 extern crate util;
-extern crate url;
 
 pub mod mem;
 pub mod time;
--- a/servo/components/profile/mem.rs
+++ b/servo/components/profile/mem.rs
@@ -1,91 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Memory profiling functions.
 
+use profile_traits::mem::{ProfilerChan, ProfilerMsg, Reporter, ReportsChan};
 use self::system_reporter::SystemReporter;
 use std::borrow::ToOwned;
 use std::cmp::Ordering;
 use std::collections::HashMap;
 use std::old_io::timer::sleep;
-use std::sync::mpsc::{Sender, channel, Receiver};
+use std::sync::mpsc::{channel, Receiver};
 use std::time::duration::Duration;
 use util::task::spawn_named;
 
-#[derive(Clone)]
-pub struct ProfilerChan(pub Sender<ProfilerMsg>);
-
-impl ProfilerChan {
-    pub fn send(&self, msg: ProfilerMsg) {
-        let ProfilerChan(ref c) = *self;
-        c.send(msg).unwrap();
-    }
-}
-
-/// An easy way to build a path for a report.
-#[macro_export]
-macro_rules! path {
-    ($($x:expr),*) => {{
-        use std::borrow::ToOwned;
-        vec![$( $x.to_owned() ),*]
-    }}
-}
-
-/// A single memory-related measurement.
-pub struct Report {
-    /// The identifying path for this report.
-    pub path: Vec<String>,
-
-    /// The size, in bytes.
-    pub size: usize,
-}
-
-/// A channel through which memory reports can be sent.
-#[derive(Clone)]
-pub struct ReportsChan(pub Sender<Vec<Report>>);
-
-impl ReportsChan {
-    pub fn send(&self, report: Vec<Report>) {
-        let ReportsChan(ref c) = *self;
-        c.send(report).unwrap();
-    }
-}
-
-/// A memory reporter is capable of measuring some data structure of interest. Because it needs
-/// to be passed to and registered with the Profiler, it's typically a "small" (i.e. easily
-/// cloneable) value that provides access to a "large" data structure, e.g. a channel that can
-/// inject a request for measurements into the event queue associated with the "large" data
-/// structure.
-pub trait Reporter {
-    /// Collect one or more memory reports. Returns true on success, and false on failure.
-    fn collect_reports(&self, reports_chan: ReportsChan) -> bool;
-}
-
-/// Messages that can be sent to the memory profiler thread.
-pub enum ProfilerMsg {
-    /// Register a Reporter with the memory profiler. The String is only used to identify the
-    /// reporter so it can be unregistered later. The String must be distinct from that used by any
-    /// other registered reporter otherwise a panic will occur.
-    RegisterReporter(String, Box<Reporter + Send>),
-
-    /// Unregister a Reporter with the memory profiler. The String must match the name given when
-    /// the reporter was registered. If the String does not match the name of a registered reporter
-    /// a panic will occur.
-    UnregisterReporter(String),
-
-    /// Triggers printing of the memory profiling metrics.
-    Print,
-
-    /// Tells the memory profiler to shut down.
-    Exit,
-}
-
 pub struct Profiler {
     /// The port through which messages are received.
     pub port: Receiver<ProfilerMsg>,
 
     /// Registered memory reporters.
     reporters: HashMap<String, Box<Reporter + Send>>,
 }
 
@@ -358,21 +291,21 @@ impl ReportsForest {
         }
     }
 }
 
 //---------------------------------------------------------------------------
 
 mod system_reporter {
     use libc::{c_char, c_int, c_void, size_t};
+    use profile_traits::mem::{Report, Reporter, ReportsChan};
     use std::borrow::ToOwned;
     use std::ffi::CString;
     use std::mem::size_of;
     use std::ptr::null_mut;
-    use super::{Report, Reporter, ReportsChan};
     #[cfg(target_os="macos")]
     use task_info::task_basic_info::{virtual_size, resident_size};
 
     /// Collects global measurements from the OS and heap allocators.
     pub struct SystemReporter;
 
     impl Reporter for SystemReporter {
         fn collect_reports(&self, reports_chan: ReportsChan) -> bool {
--- a/servo/components/profile/time.rs
+++ b/servo/components/profile/time.rs
@@ -1,45 +1,27 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Timing functions.
 
 use collections::BTreeMap;
+use profile_traits::time::{ProfilerCategory, ProfilerChan, ProfilerMsg, TimerMetadata};
 use std::borrow::ToOwned;
 use std::cmp::Ordering;
 use std::f64;
 use std::old_io::timer::sleep;
 use std::iter::AdditiveIterator;
 use std::num::Float;
-use std::sync::mpsc::{Sender, channel, Receiver};
+use std::sync::mpsc::{channel, Receiver};
 use std::time::duration::Duration;
 use std_time::precise_time_ns;
-use url::Url;
 use util::task::spawn_named;
 
-// front-end representation of the profiler used to communicate with the profiler
-#[derive(Clone)]
-pub struct ProfilerChan(pub Sender<ProfilerMsg>);
-
-impl ProfilerChan {
-    pub fn send(&self, msg: ProfilerMsg) {
-        let ProfilerChan(ref c) = *self;
-        c.send(msg).unwrap();
-    }
-}
-
-#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
-pub struct TimerMetadata {
-    url:         String,
-    iframe:      bool,
-    incremental: bool,
-}
-
 pub trait Formattable {
     fn format(&self) -> String;
 }
 
 impl Formattable for Option<TimerMetadata> {
     fn format(&self) -> String {
         match self {
             // TODO(cgaebel): Center-align in the format strings as soon as rustc supports it.
@@ -55,48 +37,16 @@ impl Formattable for Option<TimerMetadat
                 format!(" {:14} {:9} {:30}", incremental, iframe, url)
             },
             &None =>
                 format!(" {:14} {:9} {:30}", "    N/A", "  N/A", "             N/A")
         }
     }
 }
 
-#[derive(Clone)]
-pub enum ProfilerMsg {
-    /// Normal message used for reporting time
-    Time((ProfilerCategory, Option<TimerMetadata>), f64),
-    /// Message used to force print the profiling metrics
-    Print,
-    /// Tells the profiler to shut down.
-    Exit,
-}
-
-#[repr(u32)]
-#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
-pub enum ProfilerCategory {
-    Compositing,
-    LayoutPerform,
-    LayoutStyleRecalc,
-    LayoutRestyleDamagePropagation,
-    LayoutNonIncrementalReset,
-    LayoutSelectorMatch,
-    LayoutTreeBuilder,
-    LayoutDamagePropagate,
-    LayoutGeneratedContent,
-    LayoutMain,
-    LayoutParallelWarmup,
-    LayoutShaping,
-    LayoutDispListBuild,
-    PaintingPerTile,
-    PaintingPrepBuff,
-    Painting,
-    ImageDecoding,
-}
-
 impl Formattable for ProfilerCategory {
     // some categories are subcategories of LayoutPerformCategory
     // and should be printed to indicate this
     fn format(&self) -> String {
         let padding = match *self {
             ProfilerCategory::LayoutStyleRecalc |
             ProfilerCategory::LayoutRestyleDamagePropagation |
             ProfilerCategory::LayoutNonIncrementalReset |
@@ -249,51 +199,16 @@ impl Profiler {
                 println!("{:-35}{} {:15.4} {:15.4} {:15.4} {:15.4} {:15}",
                          category.format(), meta.format(), mean, median, min, max, data_len);
             }
         }
         println!("");
     }
 }
 
-#[derive(Eq, PartialEq)]
-pub enum TimerMetadataFrameType {
-    RootWindow,
-    IFrame,
-}
-
-#[derive(Eq, PartialEq)]
-pub enum TimerMetadataReflowType {
-    Incremental,
-    FirstReflow,
-}
-
-pub type ProfilerMetadata<'a> = Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>;
-
-pub fn profile<T, F>(category: ProfilerCategory,
-                     meta: ProfilerMetadata,
-                     profiler_chan: ProfilerChan,
-                     callback: F)
-                  -> T
-    where F: FnOnce() -> T
-{
-    let start_time = precise_time_ns();
-    let val = callback();
-    let end_time = precise_time_ns();
-    let ms = (end_time - start_time) as f64 / 1000000f64;
-    let meta = meta.map(|(url, iframe, reflow_type)|
-        TimerMetadata {
-            url: url.serialize(),
-            iframe: iframe == TimerMetadataFrameType::IFrame,
-            incremental: reflow_type == TimerMetadataReflowType::Incremental,
-        });
-    profiler_chan.send(ProfilerMsg::Time((category, meta), ms));
-    return val;
-}
-
 pub fn time<T, F>(msg: &str, callback: F) -> T
     where F: Fn() -> T
 {
     let start_time = precise_time_ns();
     let val = callback();
     let end_time = precise_time_ns();
     let ms = (end_time - start_time) as f64 / 1000000f64;
     if ms >= 5f64 {
new file mode 100644
--- /dev/null
+++ b/servo/components/profile_traits/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "profile_traits"
+version = "0.0.1"
+authors = ["The Servo Project Developers"]
+
+[lib]
+name = "profile_traits"
+path = "lib.rs"
+
+[dependencies]
+time = "0.1.12"
+url = "0.2.16"
+
copy from servo/tests/unit/gfx/lib.rs
copy to servo/components/profile_traits/lib.rs
--- a/servo/tests/unit/gfx/lib.rs
+++ b/servo/components/profile_traits/lib.rs
@@ -1,7 +1,6 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-extern crate gfx;
-
-#[cfg(test)] mod text_util;
+pub mod mem;
+pub mod time;
new file mode 100644
--- /dev/null
+++ b/servo/components/profile_traits/mem.rs
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use std::sync::mpsc::Sender;
+
+#[derive(Clone)]
+pub struct ProfilerChan(pub Sender<ProfilerMsg>);
+
+impl ProfilerChan {
+    pub fn send(&self, msg: ProfilerMsg) {
+        let ProfilerChan(ref c) = *self;
+        c.send(msg).unwrap();
+    }
+}
+
+/// A single memory-related measurement.
+pub struct Report {
+    /// The identifying path for this report.
+    pub path: Vec<String>,
+
+    /// The size, in bytes.
+    pub size: usize,
+}
+
+/// A channel through which memory reports can be sent.
+#[derive(Clone)]
+pub struct ReportsChan(pub Sender<Vec<Report>>);
+
+impl ReportsChan {
+    pub fn send(&self, report: Vec<Report>) {
+        let ReportsChan(ref c) = *self;
+        c.send(report).unwrap();
+    }
+}
+
+/// A memory reporter is capable of measuring some data structure of interest. Because it needs to
+/// be passed to and registered with the Profiler, it's typically a "small" (i.e. easily cloneable)
+/// value that provides access to a "large" data structure, e.g. a channel that can inject a
+/// request for measurements into the event queue associated with the "large" data structure.
+pub trait Reporter {
+    /// Collect one or more memory reports. Returns true on success, and false on failure.
+    fn collect_reports(&self, reports_chan: ReportsChan) -> bool;
+}
+
+/// An easy way to build a path for a report.
+#[macro_export]
+macro_rules! path {
+    ($($x:expr),*) => {{
+        use std::borrow::ToOwned;
+        vec![$( $x.to_owned() ),*]
+    }}
+}
+
+/// Messages that can be sent to the memory profiler thread.
+pub enum ProfilerMsg {
+    /// Register a Reporter with the memory profiler. The String is only used to identify the
+    /// reporter so it can be unregistered later. The String must be distinct from that used by any
+    /// other registered reporter otherwise a panic will occur.
+    RegisterReporter(String, Box<Reporter + Send>),
+
+    /// Unregister a Reporter with the memory profiler. The String must match the name given when
+    /// the reporter was registered. If the String does not match the name of a registered reporter
+    /// a panic will occur.
+    UnregisterReporter(String),
+
+    /// Triggers printing of the memory profiling metrics.
+    Print,
+
+    /// Tells the memory profiler to shut down.
+    Exit,
+}
new file mode 100644
--- /dev/null
+++ b/servo/components/profile_traits/time.rs
@@ -0,0 +1,95 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+extern crate "time" as std_time;
+extern crate url;
+
+use self::std_time::precise_time_ns;
+use self::url::Url;
+use std::sync::mpsc::Sender;
+
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
+pub struct TimerMetadata {
+    pub url:         String,
+    pub iframe:      bool,
+    pub incremental: bool,
+}
+
+#[derive(Clone)]
+pub struct ProfilerChan(pub Sender<ProfilerMsg>);
+
+impl ProfilerChan {
+    pub fn send(&self, msg: ProfilerMsg) {
+        let ProfilerChan(ref c) = *self;
+        c.send(msg).unwrap();
+    }
+}
+
+#[derive(Clone)]
+pub enum ProfilerMsg {
+    /// Normal message used for reporting time
+    Time((ProfilerCategory, Option<TimerMetadata>), f64),
+    /// Message used to force print the profiling metrics
+    Print,
+    /// Tells the profiler to shut down.
+    Exit,
+}
+
+#[repr(u32)]
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
+pub enum ProfilerCategory {
+    Compositing,
+    LayoutPerform,
+    LayoutStyleRecalc,
+    LayoutRestyleDamagePropagation,
+    LayoutNonIncrementalReset,
+    LayoutSelectorMatch,
+    LayoutTreeBuilder,
+    LayoutDamagePropagate,
+    LayoutGeneratedContent,
+    LayoutMain,
+    LayoutParallelWarmup,
+    LayoutShaping,
+    LayoutDispListBuild,
+    PaintingPerTile,
+    PaintingPrepBuff,
+    Painting,
+    ImageDecoding,
+}
+
+#[derive(Eq, PartialEq)]
+pub enum TimerMetadataFrameType {
+    RootWindow,
+    IFrame,
+}
+
+#[derive(Eq, PartialEq)]
+pub enum TimerMetadataReflowType {
+    Incremental,
+    FirstReflow,
+}
+
+pub type ProfilerMetadata<'a> =
+    Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>;
+
+pub fn profile<T, F>(category: ProfilerCategory,
+                     meta: ProfilerMetadata,
+                     profiler_chan: ProfilerChan,
+                     callback: F)
+                  -> T
+    where F: FnOnce() -> T
+{
+    let start_time = precise_time_ns();
+    let val = callback();
+    let end_time = precise_time_ns();
+    let ms = (end_time - start_time) as f64 / 1000000f64;
+    let meta = meta.map(|(url, iframe, reflow_type)|
+        TimerMetadata {
+            url: url.serialize(),
+            iframe: iframe == TimerMetadataFrameType::IFrame,
+            incremental: reflow_type == TimerMetadataReflowType::Incremental,
+        });
+    profiler_chan.send(ProfilerMsg::Time((category, meta), ms));
+    return val;
+}
--- a/servo/components/script/Cargo.toml
+++ b/servo/components/script/Cargo.toml
@@ -19,18 +19,18 @@ path = "../plugins"
 path = "../util"
 
 [dependencies.msg]
 path = "../msg"
 
 [dependencies.net_traits]
 path = "../net_traits"
 
-[dependencies.profile]
-path = "../profile"
+[dependencies.profile_traits]
+path = "../profile_traits"
 
 [dependencies.script_traits]
 path = "../script_traits"
 
 [dependencies.devtools_traits]
 path = "../devtools_traits"
 
 [dependencies.style]
--- a/servo/components/script/layout_interface.rs
+++ b/servo/components/script/layout_interface.rs
@@ -7,17 +7,17 @@
 //! the DOM to be placed in a separate crate from layout.
 
 use dom::node::LayoutData;
 
 use geom::point::Point2D;
 use geom::rect::Rect;
 use libc::uintptr_t;
 use msg::constellation_msg::{PipelineExitType, WindowSizeData};
-use profile::mem::{Reporter, ReportsChan};
+use profile_traits::mem::{Reporter, ReportsChan};
 use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel, UntrustedNodeAddress};
 use std::any::Any;
 use std::sync::mpsc::{channel, Receiver, Sender};
 use std::boxed::BoxAny;
 use style::animation::PropertyAnimation;
 use style::media_queries::MediaQueryList;
 use style::stylesheets::Stylesheet;
 use url::Url;
--- a/servo/components/script/lib.rs
+++ b/servo/components/script/lib.rs
@@ -38,17 +38,17 @@ extern crate hyper;
 extern crate js;
 extern crate libc;
 extern crate msg;
 extern crate net_traits;
 extern crate png;
 extern crate "rustc-serialize" as rustc_serialize;
 extern crate time;
 extern crate canvas;
-extern crate profile;
+extern crate profile_traits;
 extern crate script_traits;
 extern crate selectors;
 extern crate util;
 #[macro_use]
 extern crate style;
 extern crate url;
 extern crate uuid;
 extern crate string_cache;
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -12,16 +12,17 @@ dependencies = [
  "glutin_app 0.0.1",
  "layout 0.0.1",
  "msg 0.0.1",
  "net 0.0.1",
  "net_tests 0.0.1",
  "net_traits 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script 0.0.1",
  "script_tests 0.0.1",
  "style_tests 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "util_tests 0.0.1",
  "webdriver_server 0.0.1",
@@ -116,17 +117,17 @@ dependencies = [
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "layout_traits 0.0.1",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net 0.0.1",
  "net_traits 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "webdriver_traits 0.0.1",
 ]
 
 [[package]]
@@ -343,17 +344,17 @@ dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "skia 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -556,17 +557,17 @@ dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gfx 0.0.1",
  "layout_traits 0.0.1",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script 0.0.1",
  "script_traits 0.0.1",
  "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_plugin 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -575,17 +576,17 @@ dependencies = [
 
 [[package]]
 name = "layout_traits"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
  "msg 0.0.1",
  "net_traits 0.0.1",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "lazy_static"
 version = "0.1.8"
@@ -669,46 +670,43 @@ version = "0.0.1"
 dependencies = [
  "cookie 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "net_traits 0.0.1",
  "openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
  "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex_macros 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "net_tests"
 version = "0.0.1"
 dependencies = [
  "cookie 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "net 0.0.1",
  "net_traits 0.0.1",
- "profile 0.0.1",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "net_traits"
 version = "0.0.1"
 dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "offscreen_gl_context"
 version = "0.0.1"
@@ -804,21 +802,29 @@ name = "png-sys"
 version = "1.6.16"
 source = "git+https://github.com/servo/rust-png#1d9c59c97598014860077f372443ae98b35ff4d9"
 
 [[package]]
 name = "profile"
 version = "0.0.1"
 dependencies = [
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "profile_traits 0.0.1",
  "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "task_info 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "util 0.0.1",
+]
+
+[[package]]
+name = "profile_traits"
+version = "0.0.1"
+dependencies = [
+ "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "util 0.0.1",
 ]
 
 [[package]]
 name = "rand"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -857,17 +863,17 @@ dependencies = [
  "html5ever 0.0.0 (git+https://github.com/servo/html5ever)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_plugin 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/servo/components/servo/Cargo.toml
+++ b/servo/components/servo/Cargo.toml
@@ -62,16 +62,19 @@ path = "../net"
 path = "../net_traits"
 
 [dependencies.msg]
 path = "../msg"
 
 [dependencies.profile]
 path = "../profile"
 
+[dependencies.profile_traits]
+path = "../profile_traits"
+
 [dependencies.util]
 path = "../util"
 
 [dependencies.script]
 path = "../script"
 
 [dependencies.layout]
 path = "../layout"
--- a/servo/components/servo/lib.rs
+++ b/servo/components/servo/lib.rs
@@ -21,16 +21,17 @@
 
 extern crate compositing;
 extern crate devtools;
 extern crate devtools_traits;
 extern crate net;
 extern crate net_traits;
 extern crate msg;
 extern crate profile;
+extern crate profile_traits;
 #[macro_use]
 extern crate util;
 extern crate script;
 extern crate layout;
 extern crate gfx;
 extern crate libc;
 extern crate url;
 extern crate webdriver_server;
@@ -47,18 +48,20 @@ use msg::constellation_msg::Constellatio
 use script::dom::bindings::codegen::RegisterBindings;
 
 use net::image_cache_task::new_image_cache_task;
 use net::storage_task::StorageTaskFactory;
 use net::resource_task::new_resource_task;
 use net_traits::storage_task::StorageTask;
 
 use gfx::font_cache_task::FontCacheTask;
-use profile::mem;
-use profile::time;
+use profile::mem as profile_mem;
+use profile::time as profile_time;
+use profile_traits::mem;
+use profile_traits::time;
 use util::opts;
 
 use std::rc::Rc;
 use std::sync::mpsc::Sender;
 
 pub struct Browser {
     compositor: Box<CompositorEventListener + 'static>,
 }
@@ -87,18 +90,18 @@ impl Browser  {
         RegisterBindings::RegisterProxyHandlers();
 
         // Get both endpoints of a special channel for communication between
         // the client window and the compositor. This channel is unique because
         // messages to client may need to pump a platform-specific event loop
         // to deliver the message.
         let (compositor_proxy, compositor_receiver) =
             WindowMethods::create_compositor_channel(&window);
-        let time_profiler_chan = time::Profiler::create(opts.time_profiler_period);
-        let mem_profiler_chan = mem::Profiler::create(opts.mem_profiler_period);
+        let time_profiler_chan = profile_time::Profiler::create(opts.time_profiler_period);
+        let mem_profiler_chan = profile_mem::Profiler::create(opts.mem_profiler_period);
         let devtools_chan = opts.devtools_port.map(|port| {
             devtools::start_server(port)
         });
 
         // Create the constellation, which maintains the engine
         // pipelines, including the script and layout threads, as well
         // as the navigation context.
         let constellation_chan = create_constellation(opts.clone(),
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -114,17 +114,17 @@ dependencies = [
  "gleam 0.0.1 (git+https://github.com/servo/gleam)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "layout_traits 0.0.1",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net 0.0.1",
  "net_traits 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "webdriver_traits 0.0.1",
 ]
 
 [[package]]
@@ -341,17 +341,17 @@ dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "harfbuzz 0.1.0 (git+https://github.com/servo/rust-harfbuzz)",
  "layers 0.1.0 (git+https://github.com/servo/rust-layers)",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "skia 0.0.20130412 (git+https://github.com/servo/skia?branch=upstream-2014-06-16)",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -547,17 +547,17 @@ dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "gfx 0.0.1",
  "layout_traits 0.0.1",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script 0.0.1",
  "script_traits 0.0.1",
  "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_plugin 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -566,17 +566,17 @@ dependencies = [
 
 [[package]]
 name = "layout_traits"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
  "msg 0.0.1",
  "net_traits 0.0.1",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "lazy_static"
 version = "0.1.8"
@@ -660,33 +660,31 @@ version = "0.0.1"
 dependencies = [
  "cookie 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "net_traits 0.0.1",
  "openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
  "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex_macros 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "net_traits"
 version = "0.0.1"
 dependencies = [
  "geom 0.1.0 (git+https://github.com/servo/rust-geom)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
  "stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
 ]
 
 [[package]]
 name = "offscreen_gl_context"
 version = "0.0.1"
@@ -782,21 +780,29 @@ name = "png-sys"
 version = "1.6.16"
 source = "git+https://github.com/servo/rust-png#1d9c59c97598014860077f372443ae98b35ff4d9"
 
 [[package]]
 name = "profile"
 version = "0.0.1"
 dependencies = [
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "profile_traits 0.0.1",
  "regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "task_info 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "util 0.0.1",
+]
+
+[[package]]
+name = "profile_traits"
+version = "0.0.1"
+dependencies = [
+ "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "util 0.0.1",
 ]
 
 [[package]]
 name = "rand"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -835,17 +841,17 @@ dependencies = [
  "html5ever 0.0.0 (git+https://github.com/servo/html5ever)",
  "hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
  "libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "plugins 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
- "profile 0.0.1",
+ "profile_traits 0.0.1",
  "rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "selectors 0.1.0 (git+https://github.com/servo/rust-selectors)",
  "string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
  "string_cache_plugin 0.0.0 (git+https://github.com/servo/string-cache)",
  "style 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -891,16 +897,17 @@ dependencies = [
  "gfx 0.0.1",
  "glutin_app 0.0.1",
  "layout 0.0.1",
  "msg 0.0.1",
  "net 0.0.1",
  "net_traits 0.0.1",
  "png 0.1.0 (git+https://github.com/servo/rust-png)",
  "profile 0.0.1",
+ "profile_traits 0.0.1",
  "script 0.0.1",
  "time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "webdriver_server 0.0.1",
 ]
 
 [[package]]
--- a/servo/tests/unit/net/Cargo.toml
+++ b/servo/tests/unit/net/Cargo.toml
@@ -9,18 +9,15 @@ path = "lib.rs"
 doctest = false
 
 [dependencies.net]
 path = "../../../components/net"
 
 [dependencies.net_traits]
 path = "../../../components/net_traits"
 
-[dependencies.profile]
-path = "../../../components/profile"
-
 [dependencies.util]
 path = "../../../components/util"
 
 [dependencies]
 cookie = "*"
 hyper = "*"
 url = "*"
--- a/servo/tests/unit/net/lib.rs
+++ b/servo/tests/unit/net/lib.rs
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #![cfg_attr(test, feature(net, alloc, path, io))]
 
 extern crate net;
 extern crate net_traits;
-extern crate profile;
 extern crate url;
 extern crate util;
 
 #[cfg(test)] mod cookie;
 #[cfg(test)] mod data_loader;
 #[cfg(test)] mod mime_classifier;
 #[cfg(test)] mod resource_task;