Skip to content

Commit

Permalink
Measure Arc<Locked<T>> fields properly.
Browse files Browse the repository at this point in the history
Currently when we measure various Arc<Locked<T>> fields we don't measure the T
itself, but only the descendants of the T. This patch fixes this.

This fix requires introducing a new trait, MallocUnconditionalShallowSizeOf,
which is implemented for servo_arc::Arc. A similar trait,
MallocConditionalShallowSizeOf, is also introduced, though it has no uses as
yet.
  • Loading branch information
nnethercote committed Sep 12, 2017
1 parent 7f4cb18 commit 779fbda
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 22 deletions.
37 changes: 33 additions & 4 deletions components/malloc_size_of/lib.rs
Expand Up @@ -141,9 +141,10 @@ pub trait MallocSizeOf {

/// Trait for measuring the "shallow" heap usage of a container.
pub trait MallocShallowSizeOf {
/// Measure the heap usage of direct descendant structures, but not the
/// space taken up by the value itself. Anything pointed to by the
/// immediate children must be measured separately, using iteration.
/// Measure the heap usage of immediate heap-allocated descendant
/// structures, but not the space taken up by the value itself. Anything
/// beyond the immediate descendants must be measured separately, using
/// iteration.
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
}

Expand All @@ -156,6 +157,12 @@ pub trait MallocUnconditionalSizeOf {
fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
}

/// `MallocUnconditionalSizeOf` combined with `MallocShallowSizeOf`.
pub trait MallocUnconditionalShallowSizeOf {
/// `unconditional_size_of` combined with `shallow_size_of`.
fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
}

/// Like `MallocSizeOf`, but only measures if the value hasn't already been
/// measured. For use with types like `Rc` and `Arc` when appropriate (e.g.
/// when there is no "primary" reference).
Expand All @@ -166,6 +173,12 @@ pub trait MallocConditionalSizeOf {
fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
}

/// `MallocConditionalSizeOf` combined with `MallocShallowSizeOf`.
pub trait MallocConditionalShallowSizeOf {
/// `conditional_size_of` combined with `shallow_size_of`.
fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
}

impl<T> MallocShallowSizeOf for Box<T> {
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
ops.malloc_size_of(&**self)
Expand Down Expand Up @@ -294,9 +307,25 @@ impl<K, V, S> MallocSizeOf for HashMap<K, V, S>
//impl<T> !MallocSizeOf for Arc<T> { }
//impl<T> !MallocShallowSizeOf for Arc<T> { }

impl<T> MallocUnconditionalShallowSizeOf for Arc<T> {
fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
ops.malloc_size_of(self.heap_ptr())
}
}

impl<T: MallocSizeOf> MallocUnconditionalSizeOf for Arc<T> {
fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
ops.malloc_size_of(self.heap_ptr()) + (**self).size_of(ops)
self.unconditional_shallow_size_of(ops) + (**self).size_of(ops)
}
}

impl<T> MallocConditionalShallowSizeOf for Arc<T> {
fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
if ops.have_seen_ptr(self.heap_ptr()) {
0
} else {
self.unconditional_shallow_size_of(ops)
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions components/style/stylesheets/document_rule.rs
Expand Up @@ -8,7 +8,7 @@

use cssparser::{Parser, Token, SourceLocation, BasicParseError};
#[cfg(feature = "gecko")]
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use media_queries::Device;
use parser::{Parse, ParserContext};
use servo_arc::Arc;
Expand All @@ -34,7 +34,8 @@ impl DocumentRule {
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).size_of(guard, ops)
self.rules.unconditional_shallow_size_of(ops) +
self.rules.read_with(guard).size_of(guard, ops)
}
}

Expand Down
5 changes: 3 additions & 2 deletions components/style/stylesheets/media_rule.rs
Expand Up @@ -8,7 +8,7 @@

use cssparser::SourceLocation;
#[cfg(feature = "gecko")]
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use media_queries::MediaList;
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
Expand All @@ -34,7 +34,8 @@ impl MediaRule {
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).size_of(guard, ops)
self.rules.unconditional_shallow_size_of(ops) +
self.rules.read_with(guard).size_of(guard, ops)
}
}

Expand Down
17 changes: 11 additions & 6 deletions components/style/stylesheets/mod.rs
Expand Up @@ -26,7 +26,7 @@ pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter;
#[cfg(feature = "gecko")]
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use parser::{ParserContext, ParserErrorContext};
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
Expand Down Expand Up @@ -120,21 +120,26 @@ impl CssRule {
// it on the C++ side in the child list of the ServoStyleSheet.
CssRule::Import(_) => 0,

CssRule::Style(ref lock) => lock.read_with(guard).size_of(guard, ops),
CssRule::Style(ref lock) =>
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),

CssRule::Media(ref lock) => lock.read_with(guard).size_of(guard, ops),
CssRule::Media(ref lock) =>
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),

CssRule::FontFace(_) => 0,
CssRule::FontFeatureValues(_) => 0,
CssRule::CounterStyle(_) => 0,
CssRule::Viewport(_) => 0,
CssRule::Keyframes(_) => 0,

CssRule::Supports(ref lock) => lock.read_with(guard).size_of(guard, ops),
CssRule::Supports(ref lock) =>
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),

CssRule::Page(ref lock) => lock.read_with(guard).size_of(guard, ops),
CssRule::Page(ref lock) =>
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),

CssRule::Document(ref lock) => lock.read_with(guard).size_of(guard, ops),
CssRule::Document(ref lock) =>
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions components/style/stylesheets/page_rule.rs
Expand Up @@ -8,7 +8,7 @@

use cssparser::SourceLocation;
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use properties::PropertyDeclarationBlock;
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
Expand Down Expand Up @@ -37,7 +37,7 @@ impl PageRule {
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
// Measurement of other fields may be added later.
self.block.read_with(guard).size_of(ops)
self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops)
}
}

Expand Down
5 changes: 3 additions & 2 deletions components/style/stylesheets/style_rule.rs
Expand Up @@ -6,7 +6,7 @@

use cssparser::SourceLocation;
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use properties::PropertyDeclarationBlock;
use selector_parser::SelectorImpl;
use selectors::SelectorList;
Expand Down Expand Up @@ -58,7 +58,8 @@ impl StyleRule {
n += ops.malloc_size_of(selector.thin_arc_heap_ptr());
}

n += self.block.read_with(guard).size_of(ops);
n += self.block.unconditional_shallow_size_of(ops) +
self.block.read_with(guard).size_of(ops);

n
}
Expand Down
5 changes: 3 additions & 2 deletions components/style/stylesheets/stylesheet.rs
Expand Up @@ -10,7 +10,7 @@ use fallible::FallibleVec;
use fnv::FnvHashMap;
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
#[cfg(feature = "gecko")]
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use media_queries::{MediaList, Device};
use parking_lot::RwLock;
use parser::{ParserContext, ParserErrorContext};
Expand Down Expand Up @@ -122,7 +122,8 @@ impl StylesheetContents {
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).size_of(guard, ops)
self.rules.unconditional_shallow_size_of(ops) +
self.rules.read_with(guard).size_of(guard, ops)
}
}

Expand Down
5 changes: 3 additions & 2 deletions components/style/stylesheets/supports_rule.rs
Expand Up @@ -7,7 +7,7 @@
use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput};
use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
#[cfg(feature = "gecko")]
use malloc_size_of::MallocSizeOfOps;
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use parser::ParserContext;
use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration};
use selectors::parser::SelectorParseError;
Expand Down Expand Up @@ -37,7 +37,8 @@ impl SupportsRule {
#[cfg(feature = "gecko")]
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).size_of(guard, ops)
self.rules.unconditional_shallow_size_of(ops) +
self.rules.read_with(guard).size_of(guard, ops)
}
}

Expand Down

0 comments on commit 779fbda

Please sign in to comment.