diff options
author | Anthony Weston <anthonyelliotweston@gmail.com> | 2018-03-18 21:20:20 -0400 |
---|---|---|
committer | Anthony Weston <anthonyelliotweston@gmail.com> | 2018-03-27 20:35:39 -0400 |
commit | 7f7fc917586fa5ea9c0681f7a479c7ec8ad69019 (patch) | |
tree | f0896fbfdf6d623e6ffc03c28716fef2491d6412 | |
parent | 97c12bd3927c057d5610b0295f0e8320b64af5e5 (diff) | |
download | servo-7f7fc917586fa5ea9c0681f7a479c7ec8ad69019.tar.gz servo-7f7fc917586fa5ea9c0681f7a479c7ec8ad69019.zip |
Pass new method in CollectServoSizes for accurate DOM heap use reporting
-rw-r--r-- | Cargo.lock | 9 | ||||
-rw-r--r-- | components/malloc_size_of/Cargo.toml | 2 | ||||
-rw-r--r-- | components/script/Cargo.toml | 3 | ||||
-rw-r--r-- | components/script/lib.rs | 11 | ||||
-rw-r--r-- | components/script/mem.rs | 15 | ||||
-rw-r--r-- | components/script/script_runtime.rs | 23 | ||||
-rw-r--r-- | components/script/script_thread.rs | 37 |
7 files changed, 47 insertions, 53 deletions
diff --git a/Cargo.lock b/Cargo.lock index f4742622c37..ffa2d786591 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1635,7 +1635,7 @@ dependencies = [ "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", - "mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.19.0", "serde_bytes 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "servo_arc 0.1.1", @@ -1813,7 +1813,7 @@ dependencies = [ [[package]] name = "mozjs" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2490,6 +2490,7 @@ dependencies = [ "hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "jstraceable_derive 0.0.1", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2501,7 +2502,7 @@ dependencies = [ "mime_guess 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net_traits 0.0.1", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3903,7 +3904,7 @@ dependencies = [ "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum mitochondria 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f" "checksum mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1f0583e6792917f498bb3a7440f777a59353102063445ab7f5e9d1dc4ed593aa" -"checksum mozjs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ab870a85b83df2a5def5a941e5a50493994da0989067b16ab254ce1c770add" +"checksum mozjs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71268984a252907b3ee8c7dec2c0dffcf6acaba8af35a45865fa7626bc393c38" "checksum mozjs_sys 0.50.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e61a792a125b1364c5ec50255ed8343ce02dc56098f8868dd209d472c8de006a" "checksum mp3-metadata 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ab5f1d2693586420208d1200ce5a51cd44726f055b635176188137aff42c7de" "checksum mp4parse 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f821e3799bc0fd16d9b861fb02fa7ee1b5fba29f45ad591dade105c48ca9a1a0" diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml index 41d9a9cc924..45af5d4d7f6 100644 --- a/components/malloc_size_of/Cargo.toml +++ b/components/malloc_size_of/Cargo.toml @@ -23,7 +23,7 @@ app_units = "0.6" cssparser = "0.23.0" euclid = "0.17" hashglobe = { path = "../hashglobe" } -mozjs = { version = "0.4", features = ["promises"], optional = true } +mozjs = { version = "0.5.0", features = ["promises"], optional = true } selectors = { path = "../selectors" } serde_bytes = { version = "0.10", optional = true } servo_arc = { path = "../servo_arc" } diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 2e6a60f6dda..b186f0d6990 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -52,6 +52,7 @@ hyper = "0.10" hyper_serde = "0.8" image = "0.18" ipc-channel = "0.10" +itertools = "0.7.6" jstraceable_derive = {path = "../jstraceable_derive"} lazy_static = "1" libc = "0.2" @@ -62,7 +63,7 @@ metrics = {path = "../metrics"} mitochondria = "1.1.2" mime = "0.2.1" mime_guess = "1.8.0" -mozjs = { version = "0.4", features = ["promises"]} +mozjs = { version = "0.5.0", features = ["promises"]} msg = {path = "../msg"} net_traits = {path = "../net_traits"} num-traits = "0.1.32" diff --git a/components/script/lib.rs b/components/script/lib.rs index 882933ac5c9..02a86ee4d5d 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -107,7 +107,6 @@ extern crate xml5ever; #[macro_use] mod task; - mod body; pub mod clipboard_provider; mod devtools; @@ -150,7 +149,10 @@ pub mod layout_exports { } use dom::bindings::codegen::RegisterBindings; +use dom::bindings::conversions::is_dom_proxy; use dom::bindings::proxyhandler; +use dom::bindings::utils::is_platform_object; +use js::jsapi::JSObject; use script_traits::SWManagerSenders; use serviceworker_manager::ServiceWorkerManager; @@ -201,6 +203,11 @@ pub fn init_service_workers(sw_senders: SWManagerSenders) { } #[allow(unsafe_code)] +unsafe extern "C" fn is_dom_object(obj: *mut JSObject) -> bool { + !obj.is_null() && (is_platform_object(obj) || is_dom_proxy(obj)) +} + +#[allow(unsafe_code)] pub fn init() { unsafe { proxyhandler::init(); @@ -208,6 +215,8 @@ pub fn init() { // Create the global vtables used by the (generated) DOM // bindings to implement JS proxies. RegisterBindings::RegisterProxyHandlers(); + + js::glue::InitializeMemoryReporter(Some(is_dom_object)); } perform_platform_specific_initialization(); diff --git a/components/script/mem.rs b/components/script/mem.rs index 47491359a6d..7b75758a22e 100644 --- a/components/script/mem.rs +++ b/components/script/mem.rs @@ -4,24 +4,9 @@ //! Routines for handling measuring the memory usage of arbitrary DOM nodes. -use dom::bindings::conversions::get_dom_class; -use dom::bindings::reflector::DomObject; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use std::os::raw::c_void; -// This is equivalent to measuring a Box<T>, except that DOM objects lose their -// associated box in order to stash their pointers in a reserved slot of their -// JS reflector. -#[allow(unsafe_code)] -pub fn malloc_size_of_including_self<T: DomObject + MallocSizeOf>( - ops: &mut MallocSizeOfOps, obj: &T) -> usize -{ - unsafe { - let class = get_dom_class(obj.reflector().get_jsobject().get()).unwrap(); - (class.malloc_size_of)(ops, obj as *const T as *const c_void) - } -} - /// Used by codegen to include the pointer to the `MallocSizeOf` implementation of each /// IDL interface. This way we don't have to find the most-derived interface of DOM /// objects by hand in code. diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index cf42b47c5bb..f758a1131c0 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -6,6 +6,8 @@ //! script thread, the dom, and the worker threads. use dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback; +use dom::bindings::conversions::get_dom_class; +use dom::bindings::conversions::private_from_object; use dom::bindings::refcounted::{LiveDOMReferences, trace_refcounted_objects}; use dom::bindings::root::trace_roots; use dom::bindings::settings_stack; @@ -21,6 +23,7 @@ use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_Se use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback, SetEnqueuePromiseJobCallback}; use js::panic::wrap_panic; use js::rust::Runtime as RustRuntime; +use malloc_size_of::MallocSizeOfOps; use microtask::{EnqueuedPromiseCallback, Microtask}; use msg::constellation_msg::PipelineId; use profile_traits::mem::{Report, ReportKind, ReportsChan}; @@ -313,13 +316,31 @@ pub unsafe fn new_rt_and_cx() -> Runtime { } #[allow(unsafe_code)] +unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize { + match get_dom_class(obj) { + Ok(v) => { + let dom_object = private_from_object(obj) as *const c_void; + + if dom_object.is_null() { + return 0; + } + let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None); + (v.malloc_size_of)(&mut ops, dom_object) + } + Err(_e) => { + return 0; + } + } +} + +#[allow(unsafe_code)] pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> { let mut reports = vec![]; unsafe { let rt = JS_GetRuntime(cx); let mut stats = ::std::mem::zeroed(); - if CollectServoSizes(rt, &mut stats) { + if CollectServoSizes(rt, &mut stats, Some(get_size)) { let mut report = |mut path_suffix, kind, size| { let mut path = path![path_seg, "js"]; path.append(&mut path_suffix); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index d949e9d0b8c..6244228dc99 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -17,6 +17,8 @@ //! a page runs its course and the script thread returns to processing events in the main event //! loop. +extern crate itertools; + use bluetooth_traits::BluetoothRequest; use canvas_traits::webgl::WebGLPipeline; use devtools; @@ -72,8 +74,6 @@ use js::glue::GetWindowProxyClass; use js::jsapi::{JSAutoCompartment, JSContext, JS_SetWrapObjectCallbacks}; use js::jsapi::{JSTracer, SetWindowProxyClass}; use js::jsval::UndefinedValue; -use malloc_size_of::MallocSizeOfOps; -use mem::malloc_size_of_including_self; use metrics::{MAX_TASK_NS, PaintTimeMetrics}; use microtask::{MicrotaskQueue, Microtask}; use msg::constellation_msg::{BrowsingContextId, PipelineId, PipelineNamespace, TopLevelBrowsingContextId}; @@ -82,7 +82,7 @@ use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::image_cache::{ImageCache, PendingImageResponse}; use net_traits::request::{CredentialsMode, Destination, RedirectMode, RequestInit}; use net_traits::storage_thread::StorageType; -use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan}; +use profile_traits::mem::{self, OpaqueSender, ReportsChan}; use profile_traits::time::{self, ProfilerCategory, profile}; use script_layout_interface::message::{self, Msg, NewLayoutThreadInfo, ReflowGoal}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; @@ -1580,34 +1580,11 @@ impl ScriptThread { } fn collect_reports(&self, reports_chan: ReportsChan) { - let mut path_seg = String::from("url("); - let mut dom_tree_size = 0; - let mut reports = vec![]; - // Servo uses vanilla jemalloc, which doesn't have a - // malloc_enclosing_size_of function. - let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None); - - for (_, document) in self.documents.borrow().iter() { - let current_url = document.url(); - - for child in document.upcast::<Node>().traverse_preorder() { - dom_tree_size += malloc_size_of_including_self(&mut ops, &*child); - } - dom_tree_size += malloc_size_of_including_self(&mut ops, document.window()); - - if reports.len() > 0 { - path_seg.push_str(", "); - } - path_seg.push_str(current_url.as_str()); - - reports.push(Report { - path: path![format!("url({})", current_url.as_str()), "dom-tree"], - kind: ReportKind::ExplicitJemallocHeapSize, - size: dom_tree_size, - }); - } + let documents = self.documents.borrow(); + let urls = itertools::join(documents.iter().map(|(_, d)| d.url().to_string()), ", "); + let path_seg = format!("url({})", urls); - path_seg.push_str(")"); + let mut reports = vec![]; reports.extend(get_reports(self.get_cx(), path_seg)); reports_chan.send(reports); } |