servo: Merge #20430 - Pass new method in CollectServoSizes to get size of ObjectPrivateVisitor (from aeweston98:aew-issue7084); r=jdm

<!-- Please describe your changes on the following line: -->
These changes are the servo changes to allow the measurement of DOM objects with the ObjectPrivateVisitor API. Two new functions have been added MemoryReporter and get_size, which are passed as function pointers to two updated mozjs functions. Currently these changes rely on a branch version of mozjs, which has an [open pull request](https://github.com/servo/rust-mozjs/pull/409).

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #7084 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because _____

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 339146ae1566fc35e47ccc4fba1471a9123d039d

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 61df47854e0fd7725b25202c298646f52f5b4b4b
This commit is contained in:
Anthony Weston 2018-03-27 21:21:56 -04:00
parent 32f0cfbe75
commit 07097ddab9
7 changed files with 47 additions and 53 deletions

9
servo/Cargo.lock generated
View File

@ -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"

View File

@ -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" }

View File

@ -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"

View File

@ -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;
@ -200,6 +202,11 @@ pub fn init_service_workers(sw_senders: SWManagerSenders) {
ServiceWorkerManager::spawn_manager(sw_senders);
}
#[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 {
@ -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();

View File

@ -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.

View File

@ -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};
@ -312,6 +315,24 @@ pub unsafe fn new_rt_and_cx() -> Runtime {
Runtime(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![];
@ -319,7 +340,7 @@ pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
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);

View File

@ -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 documents = self.documents.borrow();
let urls = itertools::join(documents.iter().map(|(_, d)| d.url().to_string()), ", ");
let path_seg = format!("url({})", urls);
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,
});
}
path_seg.push_str(")");
reports.extend(get_reports(self.get_cx(), path_seg));
reports_chan.send(reports);
}