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

Measure cache memory usage #20391

Merged
merged 1 commit into from Apr 2, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Measure cache memory usage (#19251):

Made the memory cache data structure derive MallocSizeOf, along with
manual size_of() implementations in malloc_size_of.

Added a Measurable struct that acts as a container for fields size_of() can be called for.

Added a new IpcReceiver used for listening to messages from the memory profiler,
and used run_with_memory reporting to register a memory reporter in the thread.
Now when a message from the memory profiler arrives, report includes sizes of public and private http caches.

Updated test file.
  • Loading branch information
modal-d17 modal17
modal-d17 authored and modal17 committed Apr 1, 2018
commit af445a357d0429f68cad1bf12982c81e3a122bad

Some generated files are not rendered by default. Learn more.

@@ -23,13 +23,17 @@ app_units = "0.6"
cssparser = "0.23.0"
euclid = "0.17"
hashglobe = { path = "../hashglobe" }
hyper = "0.10"
hyper_serde = "0.8"
mozjs = { version = "0.6", features = ["promises"], optional = true }
selectors = { path = "../selectors" }
serde = "1.0.27"
serde_bytes = { version = "0.10", optional = true }
servo_arc = { path = "../servo_arc" }
smallbitvec = "1.0.3"
smallvec = "0.6"
string_cache = { version = "0.7", optional = true }
time = "0.1.17"
url = { version = "1.2", optional = true }
webrender_api = { git = "https://github.com/servo/webrender", features = ["ipc"], optional = true }
xml5ever = { version = "0.12", optional = true }
@@ -47,16 +47,20 @@ extern crate app_units;
extern crate cssparser;
extern crate euclid;
extern crate hashglobe;
extern crate hyper;
extern crate hyper_serde;
#[cfg(feature = "servo")]
extern crate mozjs as js;
extern crate selectors;
extern crate serde;
#[cfg(feature = "servo")]
extern crate serde_bytes;
extern crate servo_arc;
extern crate smallbitvec;
extern crate smallvec;
#[cfg(feature = "servo")]
extern crate string_cache;
extern crate time;
#[cfg(feature = "url")]
extern crate url;
extern crate void;
@@ -69,6 +73,7 @@ extern crate xml5ever;
use serde_bytes::ByteBuf;
use std::hash::{BuildHasher, Hash};
use std::mem::size_of;
use std::ops::{Deref, DerefMut};
use std::ops::Range;
use std::os::raw::c_void;
use void::Void;
@@ -591,6 +596,18 @@ impl<T: MallocSizeOf> MallocConditionalSizeOf for servo_arc::Arc<T> {
}
}

/// If a mutex is stored directly as a member of a data type that is being measured,
/// it is the unique owner of its contents and deserves to be measured.
///
/// If a mutex is stored inside of an Arc value as a member of a data type that is being measured,
/// the Arc will not be automatically measured so there is no risk of overcounting the mutex's
/// contents.
impl<T: MallocSizeOf> MallocSizeOf for std::sync::Mutex<T> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
(*self.lock().unwrap()).size_of(ops)
}
}

impl MallocSizeOf for smallbitvec::SmallBitVec {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if let Some(ptr) = self.heap_ptr() {
@@ -802,3 +819,90 @@ impl MallocSizeOf for xml5ever::QualName {
self.local.size_of(ops)
}
}

impl MallocSizeOf for hyper::header::Headers {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.iter().fold(0, |acc, x| {
let name = x.name();
let raw = self.get_raw(name);
acc + raw.size_of(ops)
})
}
}

impl MallocSizeOf for hyper::header::ContentType {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops)
}
}

impl MallocSizeOf for hyper::mime::Mime {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops) +
self.1.size_of(ops) +
self.2.size_of(ops)
}
}

impl MallocSizeOf for hyper::mime::Attr {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
match *self {
hyper::mime::Attr::Ext(ref s) => s.size_of(ops),
_ => 0,
}
}
}

impl MallocSizeOf for hyper::mime::Value {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
self.len() // Length of string value in bytes (not the char length of a string)!
}
}

malloc_size_of_is_0!(time::Duration);
malloc_size_of_is_0!(time::Tm);

impl<T> MallocSizeOf for hyper_serde::Serde<T> where
for <'de> hyper_serde::De<T>: serde::Deserialize<'de>,
for <'a> hyper_serde::Ser<'a, T>: serde::Serialize,
T: MallocSizeOf {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops)
}
}

// Placeholder for unique case where internals of Sender cannot be measured.
// malloc size of is 0 macro complains about type supplied!
impl<T> MallocSizeOf for std::sync::mpsc::Sender<T> {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
0
}
}

impl MallocSizeOf for hyper::status::StatusCode {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
match *self {
hyper::status::StatusCode::Unregistered(u) => u.size_of(ops),
_ => 0,
}
}
}

/// Measurable that defers to inner value and used to verify MallocSizeOf implementation in a
/// struct.
#[derive(Clone)]
pub struct Measurable<T: MallocSizeOf> (pub T);

impl<T: MallocSizeOf> Deref for Measurable<T> {
type Target = T;

fn deref(&self) -> &T {
&self.0
}
}

impl<T: MallocSizeOf> DerefMut for Measurable<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
@@ -24,6 +24,8 @@ immeta = "0.3.6"
ipc-channel = "0.10"
lazy_static = "1"
log = "0.4"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
matches = "0.1"
mime = "0.2.1"
mime_guess = "1.8.0"
@@ -33,6 +35,8 @@ openssl = "0.9"
profile_traits = {path = "../profile_traits"}
serde = "1.0"
serde_json = "1.0"
servo_allocator = {path = "../allocator"}
servo_arc = {path = "../servo_arc"}
servo_config = {path = "../config"}
servo_url = {path = "../url"}
servo-websocket = { version = "0.21", default-features = false, features = ["sync"] }
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.