Commit 60dbe9e9 authored by Nicholas Nethercote's avatar Nicholas Nethercote
Browse files

servo: Merge #18455 - Measure Arc<Locked<T>> fields properly (from...

servo: Merge #18455 - Measure Arc<Locked<T>> fields properly (from nnethercote:measure-Arc-Locked-properly); r=jdm

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.

<!-- Please describe your changes on the following line: -->

---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because they are tested in Gecko.

<!-- 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: bffe158fa40fda72e74afde2407cc02cd84d495d

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : b7e583f75900e5e58406802bab095f524b87398f
parent 6dc3a8d5
Loading
Loading
Loading
Loading
+33 −4
Original line number Diff line number Diff line
@@ -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;
}

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

+3 −2
Original line number Diff line number Diff line
@@ -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;
@@ -34,6 +34,7 @@ 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.unconditional_shallow_size_of(ops) +
            self.rules.read_with(guard).size_of(guard, ops)
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -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};
@@ -34,6 +34,7 @@ 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.unconditional_shallow_size_of(ops) +
            self.rules.read_with(guard).size_of(guard, ops)
    }
}
+11 −6
Original line number Diff line number Diff line
@@ -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};
@@ -120,9 +120,11 @@ 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,
@@ -130,11 +132,14 @@ impl CssRule {
            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),
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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};
@@ -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)
    }
}

Loading