forked from mirrors/gecko-dev
		
	Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`. <!-- 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 https://bugzilla.mozilla.org/show_bug.cgi?id=1409255 <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because testing is on the Gecko side. <!-- 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: 4c538b642e4bdfbf42c522c5a59c258a6d14546e --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f9a6feed1088d0b0be2b55d7f0c2ec9c594ac33b
		
			
				
	
	
		
			339 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			339 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#![deny(unsafe_code)]
 | 
						|
 | 
						|
extern crate malloc_size_of;
 | 
						|
#[macro_use] extern crate malloc_size_of_derive;
 | 
						|
extern crate num_traits;
 | 
						|
#[macro_use] extern crate serde;
 | 
						|
 | 
						|
use std::cmp::{self, max, min};
 | 
						|
use std::fmt;
 | 
						|
use std::ops;
 | 
						|
 | 
						|
pub trait Int:
 | 
						|
    Copy
 | 
						|
    + ops::Add<Self, Output=Self>
 | 
						|
    + ops::Sub<Self, Output=Self>
 | 
						|
    + cmp::Ord
 | 
						|
{
 | 
						|
    fn zero() -> Self;
 | 
						|
    fn one() -> Self;
 | 
						|
    fn max_value() -> Self;
 | 
						|
    fn from_usize(n: usize) -> Option<Self>;
 | 
						|
    fn to_usize(self) -> usize;
 | 
						|
}
 | 
						|
impl Int for isize {
 | 
						|
    #[inline]
 | 
						|
    fn zero() -> isize { 0 }
 | 
						|
    #[inline]
 | 
						|
    fn one() -> isize { 1 }
 | 
						|
    #[inline]
 | 
						|
    fn max_value() -> isize { ::std::isize::MAX }
 | 
						|
    #[inline]
 | 
						|
    fn from_usize(n: usize) -> Option<isize> { num_traits::NumCast::from(n) }
 | 
						|
    #[inline]
 | 
						|
    fn to_usize(self) -> usize { num_traits::NumCast::from(self).unwrap() }
 | 
						|
}
 | 
						|
impl Int for usize {
 | 
						|
    #[inline]
 | 
						|
    fn zero() -> usize { 0 }
 | 
						|
    #[inline]
 | 
						|
    fn one() -> usize { 1 }
 | 
						|
    #[inline]
 | 
						|
    fn max_value() -> usize { ::std::usize::MAX }
 | 
						|
    #[inline]
 | 
						|
    fn from_usize(n: usize) -> Option<usize> { Some(n) }
 | 
						|
    #[inline]
 | 
						|
    fn to_usize(self) -> usize { self }
 | 
						|
}
 | 
						|
 | 
						|
/// An index type to be used by a `Range`
 | 
						|
pub trait RangeIndex: Int + fmt::Debug {
 | 
						|
    type Index;
 | 
						|
    fn new(x: Self::Index) -> Self;
 | 
						|
    fn get(self) -> Self::Index;
 | 
						|
}
 | 
						|
 | 
						|
impl RangeIndex for isize {
 | 
						|
    type Index = isize;
 | 
						|
    #[inline]
 | 
						|
    fn new(x: isize) -> isize { x }
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    fn get(self) -> isize { self }
 | 
						|
}
 | 
						|
 | 
						|
impl RangeIndex for usize {
 | 
						|
    type Index = usize;
 | 
						|
    #[inline]
 | 
						|
    fn new(x: usize) -> usize { x }
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    fn get(self) -> usize { self }
 | 
						|
}
 | 
						|
 | 
						|
/// Implements a range index type with operator overloads
 | 
						|
#[macro_export]
 | 
						|
macro_rules! int_range_index {
 | 
						|
    ($(#[$attr:meta])* struct $Self_:ident($T:ty)) => (
 | 
						|
        #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
 | 
						|
        $(#[$attr])*
 | 
						|
        pub struct $Self_(pub $T);
 | 
						|
 | 
						|
        impl $Self_ {
 | 
						|
            #[inline]
 | 
						|
            pub fn to_usize(self) -> usize {
 | 
						|
                self.get() as usize
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        impl $crate::RangeIndex for $Self_ {
 | 
						|
            type Index = $T;
 | 
						|
            #[inline]
 | 
						|
            fn new(x: $T) -> $Self_ {
 | 
						|
                $Self_(x)
 | 
						|
            }
 | 
						|
 | 
						|
            #[inline]
 | 
						|
            fn get(self) -> $T {
 | 
						|
                match self { $Self_(x) => x }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        impl $crate::Int for $Self_ {
 | 
						|
            #[inline]
 | 
						|
            fn zero() -> $Self_ { $Self_($crate::Int::zero()) }
 | 
						|
            #[inline]
 | 
						|
            fn one() -> $Self_ { $Self_($crate::Int::one()) }
 | 
						|
            #[inline]
 | 
						|
            fn max_value() -> $Self_ { $Self_($crate::Int::max_value()) }
 | 
						|
            #[inline]
 | 
						|
            fn from_usize(n: usize) -> Option<$Self_> { $crate::Int::from_usize(n).map($Self_) }
 | 
						|
            #[inline]
 | 
						|
            fn to_usize(self) -> usize { self.to_usize() }
 | 
						|
        }
 | 
						|
 | 
						|
        impl ::std::ops::Add<$Self_> for $Self_ {
 | 
						|
            type Output = $Self_;
 | 
						|
 | 
						|
            #[inline]
 | 
						|
            fn add(self, other: $Self_) -> $Self_ {
 | 
						|
                $Self_(self.get() + other.get())
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        impl ::std::ops::Sub<$Self_> for $Self_ {
 | 
						|
            type Output = $Self_;
 | 
						|
 | 
						|
            #[inline]
 | 
						|
            fn sub(self, other: $Self_) -> $Self_ {
 | 
						|
                $Self_(self.get() - other.get())
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        impl ::std::ops::Neg for $Self_ {
 | 
						|
            type Output = $Self_;
 | 
						|
 | 
						|
            #[inline]
 | 
						|
            fn neg(self) -> $Self_ {
 | 
						|
                $Self_(-self.get())
 | 
						|
            }
 | 
						|
        }
 | 
						|
    )
 | 
						|
}
 | 
						|
 | 
						|
/// A range of indices
 | 
						|
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
 | 
						|
pub struct Range<I> {
 | 
						|
    begin: I,
 | 
						|
    length: I,
 | 
						|
}
 | 
						|
 | 
						|
impl<I: RangeIndex> fmt::Debug for Range<I> {
 | 
						|
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
						|
        write!(f, "[{:?} .. {:?})", self.begin(), self.end())
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/// An iterator over each index in a range
 | 
						|
pub struct EachIndex<I: RangeIndex> {
 | 
						|
    start: I,
 | 
						|
    stop: I,
 | 
						|
}
 | 
						|
 | 
						|
pub fn each_index<I: RangeIndex>(start: I, stop: I) -> EachIndex<I> {
 | 
						|
    EachIndex { start, stop }
 | 
						|
}
 | 
						|
 | 
						|
impl<I: RangeIndex> Iterator for EachIndex<I> {
 | 
						|
    type Item = I;
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    fn next(&mut self) -> Option<I> {
 | 
						|
        if self.start < self.stop {
 | 
						|
            let next = self.start;
 | 
						|
            self.start = next + I::one();
 | 
						|
            Some(next)
 | 
						|
        } else {
 | 
						|
            None
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    fn size_hint(&self) -> (usize, Option<usize>) {
 | 
						|
        if self.start < self.stop {
 | 
						|
            let len = (self.stop - self.start).to_usize();
 | 
						|
            (len, Some(len))
 | 
						|
        } else {
 | 
						|
            (0, Some(0))
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
impl<I: RangeIndex> Range<I> {
 | 
						|
    /// Create a new range from beginning and length offsets. This could be
 | 
						|
    /// denoted as `[begin, begin + length)`.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///    |-- begin ->|-- length ->|
 | 
						|
    ///    |           |            |
 | 
						|
    /// <- o - - - - - +============+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn new(begin: I, length: I) -> Range<I> {
 | 
						|
        Range { begin: begin, length: length }
 | 
						|
    }
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    pub fn empty() -> Range<I> {
 | 
						|
        Range::new(Int::zero(), Int::zero())
 | 
						|
    }
 | 
						|
 | 
						|
    /// The index offset to the beginning of the range.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///    |-- begin ->|
 | 
						|
    ///    |           |
 | 
						|
    /// <- o - - - - - +============+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn begin(&self) -> I { self.begin  }
 | 
						|
 | 
						|
    /// The index offset from the beginning to the end of the range.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///                |-- length ->|
 | 
						|
    ///                |            |
 | 
						|
    /// <- o - - - - - +============+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn length(&self) -> I { self.length }
 | 
						|
 | 
						|
    /// The index offset to the end of the range.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///    |--------- end --------->|
 | 
						|
    ///    |                        |
 | 
						|
    /// <- o - - - - - +============+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn end(&self) -> I { self.begin + self.length }
 | 
						|
 | 
						|
    /// `true` if the index is between the beginning and the end of the range.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///        false        true      false
 | 
						|
    ///          |           |          |
 | 
						|
    /// <- o - - + - - +=====+======+ - + - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn contains(&self, i: I) -> bool {
 | 
						|
        i >= self.begin() && i < self.end()
 | 
						|
    }
 | 
						|
 | 
						|
    /// `true` if the offset from the beginning to the end of the range is zero.
 | 
						|
    #[inline]
 | 
						|
    pub fn is_empty(&self) -> bool {
 | 
						|
        self.length() == Int::zero()
 | 
						|
    }
 | 
						|
 | 
						|
    /// Shift the entire range by the supplied index delta.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///                     |-- delta ->|
 | 
						|
    ///                     |           |
 | 
						|
    /// <- o - +============+ - - - - - | - - - ->
 | 
						|
    ///                                 |
 | 
						|
    /// <- o - - - - - - - +============+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn shift_by(&mut self, delta: I) {
 | 
						|
        self.begin = self.begin + delta;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Extend the end of the range by the supplied index delta.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///                     |-- delta ->|
 | 
						|
    ///                     |           |
 | 
						|
    /// <- o - - - - - +====+ - - - - - | - - - ->
 | 
						|
    ///                                 |
 | 
						|
    /// <- o - - - - - +================+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn extend_by(&mut self, delta: I) {
 | 
						|
        self.length = self.length + delta;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Move the end of the range to the target index.
 | 
						|
    ///
 | 
						|
    /// ~~~ignore
 | 
						|
    ///                               target
 | 
						|
    ///                                 |
 | 
						|
    /// <- o - - - - - +====+ - - - - - | - - - ->
 | 
						|
    ///                                 |
 | 
						|
    /// <- o - - - - - +================+ - - - ->
 | 
						|
    /// ~~~
 | 
						|
    #[inline]
 | 
						|
    pub fn extend_to(&mut self, target: I) {
 | 
						|
        self.length = target - self.begin;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Adjust the beginning offset and the length by the supplied deltas.
 | 
						|
    #[inline]
 | 
						|
    pub fn adjust_by(&mut self, begin_delta: I, length_delta: I) {
 | 
						|
        self.begin = self.begin + begin_delta;
 | 
						|
        self.length = self.length + length_delta;
 | 
						|
    }
 | 
						|
 | 
						|
    /// Set the begin and length values.
 | 
						|
    #[inline]
 | 
						|
    pub fn reset(&mut self, begin: I, length: I) {
 | 
						|
        self.begin = begin;
 | 
						|
        self.length = length;
 | 
						|
    }
 | 
						|
 | 
						|
    #[inline]
 | 
						|
    pub fn intersect(&self, other: &Range<I>) -> Range<I> {
 | 
						|
        let begin = max(self.begin(), other.begin());
 | 
						|
        let end = min(self.end(), other.end());
 | 
						|
 | 
						|
        if end < begin {
 | 
						|
            Range::empty()
 | 
						|
        } else {
 | 
						|
            Range::new(begin, end - begin)
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/// Methods for `Range`s with indices based on integer values
 | 
						|
impl<I: RangeIndex> Range<I> {
 | 
						|
    /// Returns an iterater that increments over `[begin, end)`.
 | 
						|
    #[inline]
 | 
						|
    pub fn each_index(&self) -> EachIndex<I> {
 | 
						|
        each_index(self.begin(), self.end())
 | 
						|
    }
 | 
						|
}
 |