зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central r=merge a=merge
This commit is contained in:
Коммит
e014a5cefe
|
@ -108,14 +108,6 @@ name = "glob"
|
|||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "heapsize"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js"
|
||||
version = "0.1.4"
|
||||
|
@ -124,7 +116,6 @@ dependencies = [
|
|||
"cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -340,7 +331,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
|
||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
|
||||
|
|
|
@ -46,5 +46,4 @@ path = "../src"
|
|||
lazy_static = "0.2.1"
|
||||
libc = "0.2"
|
||||
log = "0.3"
|
||||
heapsize = "0.4"
|
||||
num-traits = "0.1.32"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use glue;
|
||||
use heapsize::HeapSizeOf;
|
||||
use jsapi::root::*;
|
||||
use rust::GCMethods;
|
||||
use std::cell::UnsafeCell;
|
||||
|
@ -162,11 +161,3 @@ unsafe impl Trace for Heap<jsid> {
|
|||
glue::CallIdTracer(trc, self as *const _ as *mut Self, c_str!("id"));
|
||||
}
|
||||
}
|
||||
|
||||
// This is measured properly by the heap measurement implemented in
|
||||
// SpiderMonkey.
|
||||
impl<T: Copy + GCMethods> HeapSizeOf for Heap<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#[cfg(feature = "nonzero")]
|
||||
extern crate core;
|
||||
#[macro_use]
|
||||
extern crate heapsize;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
#[macro_use]
|
||||
|
@ -43,8 +41,6 @@ pub unsafe fn JS_ARGV(_cx: *mut JSContext, vp: *mut JS::Value) -> *mut JS::Value
|
|||
vp.offset(2)
|
||||
}
|
||||
|
||||
known_heap_size!(0, JS::Value);
|
||||
|
||||
impl JS::ObjectOpResult {
|
||||
/// Set this ObjectOpResult to true and return true.
|
||||
pub fn succeed(&mut self) -> bool {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use ac::AutoCompartment;
|
||||
use libc::c_uint;
|
||||
use heapsize::HeapSizeOf;
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::char;
|
||||
use std::ffi;
|
||||
|
@ -260,13 +259,6 @@ impl Drop for Runtime {
|
|||
}
|
||||
}
|
||||
|
||||
// This is measured through `glue::CollectServoSizes`.
|
||||
impl HeapSizeOf for Runtime {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
// Rooting API for standard JS things
|
||||
|
||||
|
|
|
@ -7566,9 +7566,10 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
|||
iter.Seek(insertion.mContainer->GetLastChild());
|
||||
StyleDisplay unused = UNSET_DISPLAY;
|
||||
nextSibling = FindNextSibling(iter, unused);
|
||||
if (nextSibling) {
|
||||
parentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (nextSibling) {
|
||||
parentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
|
||||
} else {
|
||||
parentFrame =
|
||||
::ContinuationToAppendTo(parentFrame);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
var floater = document.createElement("span");
|
||||
floater.style.cssFloat = "right";
|
||||
floater.appendChild(document.createTextNode("float"));
|
||||
|
||||
document.getElementById("s").appendChild(floater);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();">
|
||||
|
||||
<span><span id="s"><div></div></span></span>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
var floater = document.createElement("span");
|
||||
floater.style.cssFloat = "right";
|
||||
floater.appendChild(document.createTextNode("float"));
|
||||
|
||||
document.getElementById("s").appendChild(floater);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();">
|
||||
<span><span><div style="display: contents" id="s"><div></div></div></span></span>
|
||||
</body>
|
||||
</html>
|
|
@ -2051,3 +2051,4 @@ needs-focus != 1377447-1.html 1377447-2.html
|
|||
test-pref(font.size.systemFontScale,200) == 1412743.html 1412743-ref.html
|
||||
== 1419820-1.html 1419820-1-ref.html
|
||||
== 1420946-1.html 1420946-1-ref.html
|
||||
== 1424680.html 1424680-ref.html
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{"files":{".travis.yml":"ff4b4eeea4c3d6636633496f884b85e83e3613ad2bb84358b357f0cb8b8b1618","Cargo.toml":"f3a8db502210ebefe0565223738d41e1f6327bc283545789bea68fc93a599393","README.md":"9a38b16bccde5db28c34d79134f02d2cdcbbab224b9a68ace93c5b85b5ef38f2","appveyor.yml":"130e820ab60abf8d08f3a91d4b0158e6a581c180385e12850113adb362eb158c","build.rs":"e13e88ed285a829256d3c6987563a663c37e335457d090125a3e19b1a97fec8e","src/lib.rs":"024183eb6acfd9ebaa0b4bdc31aecd39dcb8bf92ab22228921f154b450b628a3","tests/tests.rs":"28ec35b89867f04be2b1a43116ee82b6f45e34efa53938e29c6727ad4da46ead"},"package":"4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"}
|
|
@ -1,19 +0,0 @@
|
|||
language: rust
|
||||
rust:
|
||||
- 1.8.0
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
notifications:
|
||||
webhooks: http://build.servo.org:54856/travis
|
||||
|
||||
script:
|
||||
- cargo test
|
||||
- "[ $TRAVIS_RUST_VERSION != nightly ] || cargo test --features unstable"
|
||||
- "[[ $TRAVIS_RUST_VERSION != nightly && $TRAVIS_RUST_VERSION != beta ]] || cargo test --manifest-path derive/Cargo.toml"
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
[package]
|
||||
name = "heapsize"
|
||||
version = "0.4.0"
|
||||
authors = [ "The Servo Project Developers" ]
|
||||
description = "Infrastructure for measuring the total runtime size of an object on the heap"
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/heapsize"
|
||||
build = "build.rs"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
kernel32-sys = "0.2.1"
|
||||
|
||||
[features]
|
||||
unstable = []
|
||||
|
||||
# https://github.com/servo/heapsize/issues/74
|
||||
flexible-tests = []
|
|
@ -1,5 +0,0 @@
|
|||
# heapsize
|
||||
|
||||
In support of measuring heap allocations in Rust programs.
|
||||
|
||||
[API Documentation](https://doc.servo.org/heapsize/)
|
|
@ -1,23 +0,0 @@
|
|||
environment:
|
||||
matrix:
|
||||
- FEATURES: ""
|
||||
- FEATURES: "unstable"
|
||||
|
||||
platform:
|
||||
- i686-pc-windows-gnu
|
||||
- i686-pc-windows-msvc
|
||||
- x86_64-pc-windows-gnu
|
||||
- x86_64-pc-windows-msvc
|
||||
|
||||
install:
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:PLATFORM}.exe"
|
||||
- rust-nightly-%PLATFORM%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
build_script:
|
||||
- cargo build --verbose --features "%FEATURES%"
|
||||
|
||||
test_script:
|
||||
- cargo test --verbose --features "%FEATURES%"
|
|
@ -1,37 +0,0 @@
|
|||
use std::env::var;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
fn main() {
|
||||
let verbose = Command::new(var("RUSTC").unwrap_or("rustc".into()))
|
||||
.arg("--version")
|
||||
.arg("--verbose")
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
let verbose = str::from_utf8(&verbose).unwrap();
|
||||
let mut commit_date = None;
|
||||
let mut release = None;
|
||||
for line in verbose.lines() {
|
||||
let mut parts = line.split(':');
|
||||
match parts.next().unwrap().trim() {
|
||||
"commit-date" => commit_date = Some(parts.next().unwrap().trim()),
|
||||
"release" => release = Some(parts.next().unwrap().trim()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let version = release.unwrap().split('-').next().unwrap();;
|
||||
let mut version_components = version.split('.').map(|s| s.parse::<u32>().unwrap());
|
||||
let version = (
|
||||
version_components.next().unwrap(),
|
||||
version_components.next().unwrap(),
|
||||
version_components.next().unwrap(),
|
||||
// "unknown" sorts after "2016-02-14", which is what we want to defaut to unprefixed
|
||||
// https://github.com/servo/heapsize/pull/44#issuecomment-187935883
|
||||
commit_date.unwrap()
|
||||
);
|
||||
assert_eq!(version_components.next(), None);
|
||||
if version < (1, 8, 0, "2016-02-14") {
|
||||
println!("cargo:rustc-cfg=prefixed_jemalloc");
|
||||
}
|
||||
}
|
|
@ -1,342 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
//! Data structure measurement.
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
extern crate kernel32;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use kernel32::{GetProcessHeap, HeapSize, HeapValidate};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{BTreeMap, HashSet, HashMap, LinkedList, VecDeque};
|
||||
use std::hash::BuildHasher;
|
||||
use std::hash::Hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::{size_of, align_of};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Get the size of a heap block.
|
||||
///
|
||||
/// Ideally Rust would expose a function like this in std::rt::heap.
|
||||
///
|
||||
/// `unsafe` because the caller must ensure that the pointer is from jemalloc.
|
||||
/// FIXME: This probably interacts badly with custom allocators:
|
||||
/// https://doc.rust-lang.org/book/custom-allocators.html
|
||||
pub unsafe fn heap_size_of<T>(ptr: *const T) -> usize {
|
||||
if ptr as usize <= align_of::<T>() {
|
||||
0
|
||||
} else {
|
||||
heap_size_of_impl(ptr as *const c_void)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
unsafe fn heap_size_of_impl(ptr: *const c_void) -> usize {
|
||||
// The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
|
||||
// platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
|
||||
// this function doesn't modify the contents of the block that `ptr` points to, so we use
|
||||
// `*const c_void` here.
|
||||
extern "C" {
|
||||
#[cfg_attr(any(prefixed_jemalloc, target_os = "macos", target_os = "android"), link_name = "je_malloc_usable_size")]
|
||||
fn malloc_usable_size(ptr: *const c_void) -> usize;
|
||||
}
|
||||
malloc_usable_size(ptr)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe fn heap_size_of_impl(mut ptr: *const c_void) -> usize {
|
||||
let heap = GetProcessHeap();
|
||||
|
||||
if HeapValidate(heap, 0, ptr) == 0 {
|
||||
ptr = *(ptr as *const *const c_void).offset(-1);
|
||||
}
|
||||
|
||||
HeapSize(heap, 0, ptr) as usize
|
||||
}
|
||||
|
||||
// The simplest trait for measuring the size of heap data structures. More complex traits that
|
||||
// return multiple measurements -- e.g. measure text separately from images -- are also possible,
|
||||
// and should be used when appropriate.
|
||||
//
|
||||
pub trait HeapSizeOf {
|
||||
/// Measure the size of any heap-allocated structures that hang off this value, but not the
|
||||
/// space taken up by the value itself (i.e. what size_of::<T> measures, more or less); that
|
||||
/// space is handled by the implementation of HeapSizeOf for Box<T> below.
|
||||
fn heap_size_of_children(&self) -> usize;
|
||||
}
|
||||
|
||||
// There are two possible ways to measure the size of `self` when it's on the heap: compute it
|
||||
// (with `::std::rt::heap::usable_size(::std::mem::size_of::<T>(), 0)`) or measure it directly
|
||||
// using the heap allocator (with `heap_size_of`). We do the latter, for the following reasons.
|
||||
//
|
||||
// * The heap allocator is the true authority for the sizes of heap blocks; its measurement is
|
||||
// guaranteed to be correct. In comparison, size computations are error-prone. (For example, the
|
||||
// `rt::heap::usable_size` function used in some of Rust's non-default allocator implementations
|
||||
// underestimate the true usable size of heap blocks, which is safe in general but would cause
|
||||
// under-measurement here.)
|
||||
//
|
||||
// * If we measure something that isn't a heap block, we'll get a crash. This keeps us honest,
|
||||
// which is important because unsafe code is involved and this can be gotten wrong.
|
||||
//
|
||||
// However, in the best case, the two approaches should give the same results.
|
||||
//
|
||||
impl<T: HeapSizeOf + ?Sized> HeapSizeOf for Box<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
// Measure size of `self`.
|
||||
unsafe {
|
||||
heap_size_of(&**self as *const T as *const c_void) + (**self).heap_size_of_children()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for [T] {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.iter().fold(0, |size, item| size + item.heap_size_of_children())
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for String {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
unsafe {
|
||||
heap_size_of(self.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> HeapSizeOf for &'a T {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
// The implementations for *mut T and *const T are designed for use cases like LinkedHashMap where
|
||||
// you have a data structure which internally maintains an e.g. HashMap parameterized with raw
|
||||
// pointers. We want to be able to rely on the standard HeapSizeOf implementation for `HashMap`,
|
||||
// and can handle the contribution of the raw pointers manually.
|
||||
//
|
||||
// These have to return 0 since we don't know if the pointer is pointing to a heap allocation or
|
||||
// even valid memory.
|
||||
impl<T: ?Sized> HeapSizeOf for *mut T {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> HeapSizeOf for *const T {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for Option<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
match *self {
|
||||
None => 0,
|
||||
Some(ref x) => x.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf, E: HeapSizeOf> HeapSizeOf for Result<T, E> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
match *self {
|
||||
Ok(ref x) => x.heap_size_of_children(),
|
||||
Err(ref e) => e.heap_size_of_children(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, B: ?Sized + ToOwned> HeapSizeOf for Cow<'a, B> where B::Owned: HeapSizeOf {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
match *self {
|
||||
Cow::Borrowed(_) => 0,
|
||||
Cow::Owned(ref b) => b.heap_size_of_children(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapSizeOf for () {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1, T2> HeapSizeOf for (T1, T2)
|
||||
where T1: HeapSizeOf, T2 :HeapSizeOf
|
||||
{
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children() +
|
||||
self.1.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1, T2, T3> HeapSizeOf for (T1, T2, T3)
|
||||
where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf
|
||||
{
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children() +
|
||||
self.1.heap_size_of_children() +
|
||||
self.2.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1, T2, T3, T4> HeapSizeOf for (T1, T2, T3, T4)
|
||||
where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf, T4: HeapSizeOf
|
||||
{
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children() +
|
||||
self.1.heap_size_of_children() +
|
||||
self.2.heap_size_of_children() +
|
||||
self.3.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T1, T2, T3, T4, T5> HeapSizeOf for (T1, T2, T3, T4, T5)
|
||||
where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf, T4: HeapSizeOf, T5: HeapSizeOf
|
||||
{
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.0.heap_size_of_children() +
|
||||
self.1.heap_size_of_children() +
|
||||
self.2.heap_size_of_children() +
|
||||
self.3.heap_size_of_children() +
|
||||
self.4.heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for Arc<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
(**self).heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for RefCell<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.borrow().heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf + Copy> HeapSizeOf for Cell<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.get().heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for Vec<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.iter().fold(
|
||||
unsafe { heap_size_of(self.as_ptr()) },
|
||||
|n, elem| n + elem.heap_size_of_children())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for VecDeque<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.iter().fold(
|
||||
// FIXME: get the buffer pointer for heap_size_of(), capacity() is a lower bound:
|
||||
self.capacity() * size_of::<T>(),
|
||||
|n, elem| n + elem.heap_size_of_children())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HeapSizeOf for Vec<Rc<T>> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
// The fate of measuring Rc<T> is still undecided, but we still want to measure
|
||||
// the space used for storing them.
|
||||
unsafe {
|
||||
heap_size_of(self.as_ptr())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf, S> HeapSizeOf for HashSet<T, S>
|
||||
where T: Eq + Hash, S: BuildHasher {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
//TODO(#6908) measure actual bucket memory usage instead of approximating
|
||||
let size = self.capacity() * (size_of::<T>() + size_of::<usize>());
|
||||
self.iter().fold(size, |n, value| {
|
||||
n + value.heap_size_of_children()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: HeapSizeOf, V: HeapSizeOf, S> HeapSizeOf for HashMap<K, V, S>
|
||||
where K: Eq + Hash, S: BuildHasher {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
//TODO(#6908) measure actual bucket memory usage instead of approximating
|
||||
let size = self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>());
|
||||
self.iter().fold(size, |n, (key, value)| {
|
||||
n + key.heap_size_of_children() + value.heap_size_of_children()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// PhantomData is always 0.
|
||||
impl<T> HeapSizeOf for PhantomData<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
// A linked list has an overhead of two words per item.
|
||||
impl<T: HeapSizeOf> HeapSizeOf for LinkedList<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
let mut size = 0;
|
||||
for item in self {
|
||||
size += 2 * size_of::<usize>() + size_of::<T>() + item.heap_size_of_children();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Overhead for the BTreeMap nodes is not accounted for.
|
||||
impl<K: HeapSizeOf, V: HeapSizeOf> HeapSizeOf for BTreeMap<K, V> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
let mut size = 0;
|
||||
for (key, value) in self.iter() {
|
||||
size += size_of::<(K, V)>() +
|
||||
key.heap_size_of_children() +
|
||||
value.heap_size_of_children();
|
||||
}
|
||||
size
|
||||
}
|
||||
}
|
||||
|
||||
/// For use on types defined in external crates
|
||||
/// with known heap sizes.
|
||||
#[macro_export]
|
||||
macro_rules! known_heap_size(
|
||||
($size:expr, $($ty:ty),+) => (
|
||||
$(
|
||||
impl $crate::HeapSizeOf for $ty {
|
||||
#[inline(always)]
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
$size
|
||||
}
|
||||
}
|
||||
)+
|
||||
);
|
||||
($size: expr, $($ty:ident<$($gen:ident),+>),+) => (
|
||||
$(
|
||||
impl<$($gen: $crate::HeapSizeOf),+> $crate::HeapSizeOf for $ty<$($gen),+> {
|
||||
#[inline(always)]
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
$size
|
||||
}
|
||||
}
|
||||
)+
|
||||
);
|
||||
);
|
||||
|
||||
known_heap_size!(0, char, str);
|
||||
known_heap_size!(0, u8, u16, u32, u64, usize);
|
||||
known_heap_size!(0, i8, i16, i32, i64, isize);
|
||||
known_heap_size!(0, bool, f32, f64);
|
||||
known_heap_size!(0, AtomicBool, AtomicIsize, AtomicUsize);
|
||||
known_heap_size!(0, Ipv4Addr, Ipv6Addr);
|
|
@ -1,190 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#![cfg_attr(feature= "unstable", feature(alloc, heap_api, repr_simd))]
|
||||
|
||||
extern crate heapsize;
|
||||
|
||||
use heapsize::{HeapSizeOf, heap_size_of};
|
||||
use std::os::raw::c_void;
|
||||
|
||||
const EMPTY: *mut () = 0x1 as *mut ();
|
||||
|
||||
/// https://github.com/servo/heapsize/issues/74
|
||||
#[cfg(feature = "flexible-tests")]
|
||||
macro_rules! assert_size {
|
||||
($actual: expr, $expected: expr) => {
|
||||
{
|
||||
let actual = $actual;
|
||||
let expected = $expected;
|
||||
assert!(actual >= expected, "expected {:?} >= {:?}", actual, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "flexible-tests"))]
|
||||
macro_rules! assert_size {
|
||||
($actual: expr, $expected: expr) => {
|
||||
assert_eq!($actual, $expected)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
mod unstable {
|
||||
extern crate alloc;
|
||||
|
||||
use heapsize::heap_size_of;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
#[repr(C, simd)]
|
||||
struct OverAligned(u64, u64, u64, u64);
|
||||
|
||||
#[test]
|
||||
fn check_empty() {
|
||||
assert_eq!(::EMPTY, alloc::heap::EMPTY);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[test]
|
||||
fn test_alloc() {
|
||||
unsafe {
|
||||
// A 64 byte request is allocated exactly.
|
||||
let x = alloc::heap::allocate(64, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 64);
|
||||
alloc::heap::deallocate(x, 64, 0);
|
||||
|
||||
// A 255 byte request is rounded up to 256 bytes.
|
||||
let x = alloc::heap::allocate(255, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 256);
|
||||
alloc::heap::deallocate(x, 255, 0);
|
||||
|
||||
// A 1MiB request is allocated exactly.
|
||||
let x = alloc::heap::allocate(1024 * 1024, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 1024 * 1024);
|
||||
alloc::heap::deallocate(x, 1024 * 1024, 0);
|
||||
|
||||
// An overaligned 1MiB request is allocated exactly.
|
||||
let x = alloc::heap::allocate(1024 * 1024, 32);
|
||||
assert_size!(heap_size_of(x as *const c_void), 1024 * 1024);
|
||||
alloc::heap::deallocate(x, 1024 * 1024, 32);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_alloc() {
|
||||
unsafe {
|
||||
// A 64 byte request is allocated exactly.
|
||||
let x = alloc::heap::allocate(64, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 64);
|
||||
alloc::heap::deallocate(x, 64, 0);
|
||||
|
||||
// A 255 byte request is allocated exactly.
|
||||
let x = alloc::heap::allocate(255, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 255);
|
||||
alloc::heap::deallocate(x, 255, 0);
|
||||
|
||||
// A 1MiB request is allocated exactly.
|
||||
let x = alloc::heap::allocate(1024 * 1024, 0);
|
||||
assert_size!(heap_size_of(x as *const c_void), 1024 * 1024);
|
||||
alloc::heap::deallocate(x, 1024 * 1024, 0);
|
||||
|
||||
// An overaligned 1MiB request is over-allocated.
|
||||
let x = alloc::heap::allocate(1024 * 1024, 32);
|
||||
assert_size!(heap_size_of(x as *const c_void), 1024 * 1024 + 32);
|
||||
alloc::heap::deallocate(x, 1024 * 1024, 32);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[test]
|
||||
fn test_simd() {
|
||||
let x = Box::new(OverAligned(0, 0, 0, 0));
|
||||
assert_size!(unsafe { heap_size_of(&*x as *const _ as *const c_void) }, 32);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn test_simd() {
|
||||
let x = Box::new(OverAligned(0, 0, 0, 0));
|
||||
assert_size!(unsafe { heap_size_of(&*x as *const _ as *const c_void) }, 32 + 32);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_str() {
|
||||
let x = "raclette".to_owned().into_boxed_str();
|
||||
assert_size!(x.heap_size_of_children(), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_heap_size() {
|
||||
|
||||
// Note: jemalloc often rounds up request sizes. However, it does not round up for request
|
||||
// sizes of 8 and higher that are powers of two. We take advantage of knowledge here to make
|
||||
// the sizes of various heap-allocated blocks predictable.
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Start with basic heap block measurement.
|
||||
|
||||
unsafe {
|
||||
// EMPTY is the special non-null address used to represent zero-size allocations.
|
||||
assert_size!(heap_size_of(EMPTY as *const c_void), 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Test HeapSizeOf implementations for various built-in types.
|
||||
|
||||
// Not on the heap; 0 bytes.
|
||||
let x = 0i64;
|
||||
assert_size!(x.heap_size_of_children(), 0);
|
||||
|
||||
// An i64 is 8 bytes.
|
||||
let x = Box::new(0i64);
|
||||
assert_size!(x.heap_size_of_children(), 8);
|
||||
|
||||
// An ascii string with 16 chars is 16 bytes in UTF-8.
|
||||
let string = String::from("0123456789abcdef");
|
||||
assert_size!(string.heap_size_of_children(), 16);
|
||||
|
||||
let string_ref: (&String, ()) = (&string, ());
|
||||
assert_size!(string_ref.heap_size_of_children(), 0);
|
||||
|
||||
let slice: &str = &*string;
|
||||
assert_size!(slice.heap_size_of_children(), 0);
|
||||
|
||||
// Not on the heap.
|
||||
let x: Option<i32> = None;
|
||||
assert_size!(x.heap_size_of_children(), 0);
|
||||
|
||||
// Not on the heap.
|
||||
let x = Some(0i64);
|
||||
assert_size!(x.heap_size_of_children(), 0);
|
||||
|
||||
// The `Some` is not on the heap, but the Box is.
|
||||
let x = Some(Box::new(0i64));
|
||||
assert_size!(x.heap_size_of_children(), 8);
|
||||
|
||||
// Not on the heap.
|
||||
let x = ::std::sync::Arc::new(0i64);
|
||||
assert_size!(x.heap_size_of_children(), 0);
|
||||
|
||||
// The `Arc` is not on the heap, but the Box is.
|
||||
let x = ::std::sync::Arc::new(Box::new(0i64));
|
||||
assert_size!(x.heap_size_of_children(), 8);
|
||||
|
||||
// Zero elements, no heap storage.
|
||||
let x: Vec<i64> = vec![];
|
||||
assert_size!(x.heap_size_of_children(), 0);
|
||||
|
||||
// Four elements, 8 bytes per element.
|
||||
let x = vec![0i64, 1i64, 2i64, 3i64];
|
||||
assert_size!(x.heap_size_of_children(), 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_slice() {
|
||||
let x = vec![1i64, 2i64].into_boxed_slice();
|
||||
assert_size!(x.heap_size_of_children(), 16)
|
||||
}
|
|
@ -2910,7 +2910,7 @@
|
|||
"record_in_processes": ["main", "content"],
|
||||
"alert_emails": ["necko@mozilla.com"],
|
||||
"bug_numbers": [1341128],
|
||||
"expires_in_version": "60",
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
"n_values": 16,
|
||||
"releaseChannelCollection": "opt-out",
|
||||
|
|
|
@ -116,7 +116,6 @@
|
|||
<command id="cmd_enableItem"/>
|
||||
<command id="cmd_disableItem"/>
|
||||
<command id="cmd_installItem"/>
|
||||
<command id="cmd_purchaseItem"/>
|
||||
<command id="cmd_uninstallItem"/>
|
||||
<command id="cmd_cancelUninstallItem"/>
|
||||
<command id="cmd_cancelOperation"/>
|
||||
|
@ -620,8 +619,6 @@
|
|||
label="&cmd.uninstallAddon.label;"
|
||||
accesskey="&cmd.uninstallAddon.accesskey;"
|
||||
command="cmd_uninstallItem"/>
|
||||
<button id="detail-purchase-btn" class="addon-control purchase"
|
||||
command="cmd_purchaseItem"/>
|
||||
<button id="detail-install-btn" class="addon-control install"
|
||||
label="&cmd.installAddon.label;"
|
||||
accesskey="&cmd.installAddon.accesskey;"
|
||||
|
|
Загрузка…
Ссылка в новой задаче