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.
This commit is contained in:
modal-d17 2018-02-20 16:00:16 -05:00 committed by modal17
parent d232705106
commit af445a357d
13 changed files with 312 additions and 76 deletions

View file

@ -47,9 +47,12 @@ 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;
@ -57,6 +60,7 @@ 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
}
}