mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
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:
parent
d232705106
commit
af445a357d
13 changed files with 312 additions and 76 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue