From 703464a516fdd61b7cc94393a297c8e82ba219e8 Mon Sep 17 00:00:00 2001 From: Noah Huesser Date: Thu, 5 Sep 2019 14:57:17 +0200 Subject: [PATCH] memory experiments --- Cargo.lock | 6 +- config/default.toml | 2 +- data/8_142_93.pbf | Bin 0 -> 104564 bytes examples/tile_mem_test.rs | 22 + malloc_size_of/Cargo.toml | 29 -- malloc_size_of/lib.rs | 831 ------------------------------------ src/bin/drawing/painter.rs | 3 - src/bin/drawing/ui.rs | 5 +- src/lib/css.rs | 11 + src/lib/object.rs | 7 +- src/lib/vector_tile/tile.rs | 19 +- 11 files changed, 52 insertions(+), 883 deletions(-) create mode 100644 data/8_142_93.pbf create mode 100644 examples/tile_mem_test.rs delete mode 100644 malloc_size_of/Cargo.toml delete mode 100644 malloc_size_of/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 50e5805..737df6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -921,7 +921,7 @@ dependencies = [ [[package]] name = "imgui-wgpu" version = "0.1.0" -source = "git+https://github.com/Yatekii/imgui-wgpu-rs#958cdaeabe764678b71b7f329d7829329b4cf875" +source = "git+https://github.com/Yatekii/imgui-wgpu-rs#1706a9654ecb7f75671e8be432a32ef076dc65a1" dependencies = [ "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1071,7 +1071,7 @@ name = "line_drawing" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1571,7 +1571,7 @@ dependencies = [ "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/config/default.toml b/config/default.toml index eaf1afc..9b38be8 100644 --- a/config/default.toml +++ b/config/default.toml @@ -10,7 +10,7 @@ ui_font = "config/Ruda-Bold.ttf" max_tiles = 200 max_features = 1000 tile_size = 384 -msaa_samples = 1 +msaa_samples = 4 selection_tags = [] [renderer.temperature] diff --git a/data/8_142_93.pbf b/data/8_142_93.pbf new file mode 100644 index 0000000000000000000000000000000000000000..ceb6de9305f31d036b03b936a8f82bd06a7403dd GIT binary patch literal 104564 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�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 sQg>TvyR3}eR$!l%x!W4?t`*#6W$m_dc3XM-t or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A crate for measuring the heap usage of data structures in a way that -//! integrates with Firefox's memory reporting, particularly the use of -//! mozjemalloc and DMD. In particular, it has the following features. -//! - It isn't bound to a particular heap allocator. -//! - It provides traits for both "shallow" and "deep" measurement, which gives -//! flexibility in the cases where the traits can't be used. -//! - It allows for measuring blocks even when only an interior pointer can be -//! obtained for heap allocations, e.g. `HashSet` and `HashMap`. (This relies -//! on the heap allocator having suitable support, which mozjemalloc has.) -//! - It allows handling of types like `Rc` and `Arc` by providing traits that -//! are different to the ones for non-graph structures. -//! -//! Suggested uses are as follows. -//! - When possible, use the `MallocSizeOf` trait. (Deriving support is -//! provided by the `malloc_size_of_derive` crate.) -//! - If you need an additional synchronization argument, provide a function -//! that is like the standard trait method, but with the extra argument. -//! - If you need multiple measurements for a type, provide a function named -//! `add_size_of` that takes a mutable reference to a struct that contains -//! the multiple measurement fields. -//! - When deep measurement (via `MallocSizeOf`) cannot be implemented for a -//! type, shallow measurement (via `MallocShallowSizeOf`) in combination with -//! iteration can be a useful substitute. -//! - `Rc` and `Arc` are always tricky, which is why `MallocSizeOf` is not (and -//! should not be) implemented for them. -//! - If an `Rc` or `Arc` is known to be a "primary" reference and can always -//! be measured, it should be measured via the `MallocUnconditionalSizeOf` -//! trait. -//! - If an `Rc` or `Arc` should be measured only if it hasn't been seen -//! before, it should be measured via the `MallocConditionalSizeOf` trait. -//! - Using universal function call syntax is a good idea when measuring boxed -//! fields in structs, because it makes it clear that the Box is being -//! measured as well as the thing it points to. E.g. -//! ` as MallocSizeOf>::size_of(field, ops)`. -//! -//! Note: WebRender has a reduced for of this crate, so that we can avoid -//! publishing this crate on crates.io. - -extern crate app_units; -#[cfg(feature = "servo")] -extern crate crossbeam_channel; -extern crate cssparser; -extern crate euclid; -#[cfg(feature = "servo")] -extern crate hyper; -#[cfg(feature = "servo")] -extern crate hyper_serde; -#[cfg(feature = "servo")] -extern crate keyboard_types; -#[cfg(feature = "servo")] -extern crate serde; -#[cfg(feature = "servo")] -extern crate serde_bytes; -extern crate smallbitvec; -extern crate smallvec; -#[cfg(feature = "servo")] -extern crate string_cache; -extern crate thin_slice; -#[cfg(feature = "servo")] -extern crate time; -#[cfg(feature = "url")] -extern crate url; -extern crate void; -#[cfg(feature = "webrender_api")] -extern crate webrender_api; -#[cfg(feature = "servo")] -extern crate xml5ever; - -#[cfg(feature = "servo")] -use serde_bytes::ByteBuf; -use std::hash::{BuildHasher, Hash}; -use std::mem::size_of; -use std::ops::Range; -use std::ops::{Deref, DerefMut}; -use std::os::raw::c_void; -use void::Void; - -/// A C function that takes a pointer to a heap allocation and returns its size. -type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize; - -/// A closure implementing a stateful predicate on pointers. -type VoidPtrToBoolFnMut = FnMut(*const c_void) -> bool; - -/// Operations used when measuring heap usage of data structures. -pub struct MallocSizeOfOps { - /// A function that returns the size of a heap allocation. - size_of_op: VoidPtrToSizeFn, - - /// Like `size_of_op`, but can take an interior pointer. Optional because - /// not all allocators support this operation. If it's not provided, some - /// memory measurements will actually be computed estimates rather than - /// real and accurate measurements. - enclosing_size_of_op: Option, - - /// Check if a pointer has been seen before, and remember it for next time. - /// Useful when measuring `Rc`s and `Arc`s. Optional, because many places - /// don't need it. - have_seen_ptr_op: Option>, -} - -impl MallocSizeOfOps { - pub fn new( - size_of: VoidPtrToSizeFn, - malloc_enclosing_size_of: Option, - have_seen_ptr: Option>, - ) -> Self { - MallocSizeOfOps { - size_of_op: size_of, - enclosing_size_of_op: malloc_enclosing_size_of, - have_seen_ptr_op: have_seen_ptr, - } - } - - /// Check if an allocation is empty. This relies on knowledge of how Rust - /// handles empty allocations, which may change in the future. - fn is_empty(ptr: *const T) -> bool { - // The correct condition is this: - // `ptr as usize <= ::std::mem::align_of::()` - // But we can't call align_of() on a ?Sized T. So we approximate it - // with the following. 256 is large enough that it should always be - // larger than the required alignment, but small enough that it is - // always in the first page of memory and therefore not a legitimate - // address. - return ptr as *const usize as usize <= 256; - } - - /// Call `size_of_op` on `ptr`, first checking that the allocation isn't - /// empty, because some types (such as `Vec`) utilize empty allocations. - pub unsafe fn malloc_size_of(&self, ptr: *const T) -> usize { - if MallocSizeOfOps::is_empty(ptr) { - 0 - } else { - (self.size_of_op)(ptr as *const c_void) - } - } - - /// Is an `enclosing_size_of_op` available? - pub fn has_malloc_enclosing_size_of(&self) -> bool { - self.enclosing_size_of_op.is_some() - } - - /// Call `enclosing_size_of_op`, which must be available, on `ptr`, which - /// must not be empty. - pub unsafe fn malloc_enclosing_size_of(&self, ptr: *const T) -> usize { - assert!(!MallocSizeOfOps::is_empty(ptr)); - (self.enclosing_size_of_op.unwrap())(ptr as *const c_void) - } - - /// Call `have_seen_ptr_op` on `ptr`. - pub fn have_seen_ptr(&mut self, ptr: *const T) -> bool { - let have_seen_ptr_op = self - .have_seen_ptr_op - .as_mut() - .expect("missing have_seen_ptr_op"); - have_seen_ptr_op(ptr as *const c_void) - } -} - -/// Trait for measuring the "deep" heap usage of a data structure. This is the -/// most commonly-used of the traits. -pub trait MallocSizeOf { - /// Measure the heap usage of all descendant heap-allocated structures, but - /// not the space taken up by the value itself. - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize; -} - -/// Trait for measuring the "shallow" heap usage of a container. -pub trait MallocShallowSizeOf { - /// 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; -} - -/// Like `MallocSizeOf`, but with a different name so it cannot be used -/// accidentally with derive(MallocSizeOf). For use with types like `Rc` and -/// `Arc` when appropriate (e.g. when measuring a "primary" reference). -pub trait MallocUnconditionalSizeOf { - /// Measure the heap usage of all heap-allocated descendant structures, but - /// not the space taken up by the value itself. - 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). -pub trait MallocConditionalSizeOf { - /// Measure the heap usage of all heap-allocated descendant structures, but - /// not the space taken up by the value itself, and only if that heap usage - /// hasn't already been measured. - 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 MallocSizeOf for String { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - unsafe { ops.malloc_size_of(self.as_ptr()) } - } -} - -impl<'a, T: ?Sized> MallocSizeOf for &'a T { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - // Zero makes sense for a non-owning reference. - 0 - } -} - -impl MallocShallowSizeOf for Box { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - unsafe { ops.malloc_size_of(&**self) } - } -} - -impl MallocSizeOf for Box { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.shallow_size_of(ops) + (**self).size_of(ops) - } -} - -impl MallocShallowSizeOf for thin_slice::ThinBoxedSlice { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = 0; - unsafe { - n += thin_slice::ThinBoxedSlice::spilled_storage(self) - .map_or(0, |ptr| ops.malloc_size_of(ptr)); - n += ops.malloc_size_of(&**self); - } - n - } -} - -impl MallocSizeOf for thin_slice::ThinBoxedSlice { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.shallow_size_of(ops) + (**self).size_of(ops) - } -} - -impl MallocSizeOf for () { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - 0 - } -} - -impl MallocSizeOf for (T1, T2) -where - T1: MallocSizeOf, - T2: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.0.size_of(ops) + self.1.size_of(ops) - } -} - -impl MallocSizeOf for (T1, T2, T3) -where - T1: MallocSizeOf, - T2: MallocSizeOf, - T3: MallocSizeOf, -{ - 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 (T1, T2, T3, T4) -where - T1: MallocSizeOf, - T2: MallocSizeOf, - T3: MallocSizeOf, - T4: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) + self.3.size_of(ops) - } -} - -impl MallocSizeOf for Option { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - if let Some(val) = self.as_ref() { - val.size_of(ops) - } else { - 0 - } - } -} - -impl MallocSizeOf for Result { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - match *self { - Ok(ref x) => x.size_of(ops), - Err(ref e) => e.size_of(ops), - } - } -} - -impl MallocSizeOf for std::cell::Cell { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.get().size_of(ops) - } -} - -impl MallocSizeOf for std::cell::RefCell { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.borrow().size_of(ops) - } -} - -impl<'a, B: ?Sized + ToOwned> MallocSizeOf for std::borrow::Cow<'a, B> -where - B::Owned: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - match *self { - std::borrow::Cow::Borrowed(_) => 0, - std::borrow::Cow::Owned(ref b) => b.size_of(ops), - } - } -} - -impl MallocSizeOf for [T] { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = 0; - for elem in self.iter() { - n += elem.size_of(ops); - } - n - } -} - -#[cfg(feature = "servo")] -impl MallocShallowSizeOf for ByteBuf { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - unsafe { ops.malloc_size_of(self.as_ptr()) } - } -} - -#[cfg(feature = "servo")] -impl MallocSizeOf for ByteBuf { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for elem in self.iter() { - n += elem.size_of(ops); - } - n - } -} - -impl MallocShallowSizeOf for Vec { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - unsafe { ops.malloc_size_of(self.as_ptr()) } - } -} - -impl MallocSizeOf for Vec { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for elem in self.iter() { - n += elem.size_of(ops); - } - n - } -} - -impl MallocShallowSizeOf for std::collections::VecDeque { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - if ops.has_malloc_enclosing_size_of() { - if let Some(front) = self.front() { - // The front element is an interior pointer. - unsafe { ops.malloc_enclosing_size_of(&*front) } - } else { - // This assumes that no memory is allocated when the VecDeque is empty. - 0 - } - } else { - // An estimate. - self.capacity() * size_of::() - } - } -} - -impl MallocSizeOf for std::collections::VecDeque { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for elem in self.iter() { - n += elem.size_of(ops); - } - n - } -} - -impl MallocShallowSizeOf for smallvec::SmallVec { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - if self.spilled() { - unsafe { ops.malloc_size_of(self.as_ptr()) } - } else { - 0 - } - } -} - -impl MallocSizeOf for smallvec::SmallVec -where - A: smallvec::Array, - A::Item: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for elem in self.iter() { - n += elem.size_of(ops); - } - n - } -} - -macro_rules! malloc_size_of_hash_set { - ($ty:ty) => { - impl MallocShallowSizeOf for $ty - where - T: Eq + Hash, - S: BuildHasher, - { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - if ops.has_malloc_enclosing_size_of() { - // The first value from the iterator gives us an interior pointer. - // `ops.malloc_enclosing_size_of()` then gives us the storage size. - // This assumes that the `HashSet`'s contents (values and hashes) - // are all stored in a single contiguous heap allocation. - self.iter() - .next() - .map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) }) - } else { - // An estimate. - self.capacity() * (size_of::() + size_of::()) - } - } - } - - impl MallocSizeOf for $ty - where - T: Eq + Hash + MallocSizeOf, - S: BuildHasher, - { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for t in self.iter() { - n += t.size_of(ops); - } - n - } - } - }; -} - -malloc_size_of_hash_set!(std::collections::HashSet); - -macro_rules! malloc_size_of_hash_map { - ($ty:ty) => { - impl MallocShallowSizeOf for $ty - where - K: Eq + Hash, - S: BuildHasher, - { - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - // See the implementation for std::collections::HashSet for details. - if ops.has_malloc_enclosing_size_of() { - self.values() - .next() - .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) - } else { - self.capacity() * (size_of::() + size_of::() + size_of::()) - } - } - } - - impl MallocSizeOf for $ty - where - K: Eq + Hash + MallocSizeOf, - V: MallocSizeOf, - S: BuildHasher, - { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for (k, v) in self.iter() { - n += k.size_of(ops); - n += v.size_of(ops); - } - n - } - } - }; -} - -malloc_size_of_hash_map!(std::collections::HashMap); - -impl MallocShallowSizeOf for std::collections::BTreeMap -where - K: Eq + Hash, -{ - fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - if ops.has_malloc_enclosing_size_of() { - self.values() - .next() - .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) - } else { - self.len() * (size_of::() + size_of::() + size_of::()) - } - } -} - -impl MallocSizeOf for std::collections::BTreeMap -where - K: Eq + Hash + MallocSizeOf, - V: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - let mut n = self.shallow_size_of(ops); - for (k, v) in self.iter() { - n += k.size_of(ops); - n += v.size_of(ops); - } - n - } -} - -// PhantomData is always 0. -impl MallocSizeOf for std::marker::PhantomData { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - 0 - } -} - -/// 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 MallocSizeOf for std::sync::Mutex { - 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() { - unsafe { ops.malloc_size_of(ptr) } - } else { - 0 - } - } -} - -impl MallocSizeOf for euclid::Length { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.0.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedScale { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.0.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedPoint2D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.x.size_of(ops) + self.y.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedRect { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.origin.size_of(ops) + self.size.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedSideOffsets2D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.top.size_of(ops) + - self.right.size_of(ops) + - self.bottom.size_of(ops) + - self.left.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedSize2D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.width.size_of(ops) + self.height.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedTransform2D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.m11.size_of(ops) + - self.m12.size_of(ops) + - self.m21.size_of(ops) + - self.m22.size_of(ops) + - self.m31.size_of(ops) + - self.m32.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedTransform3D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.m11.size_of(ops) + - self.m12.size_of(ops) + - self.m13.size_of(ops) + - self.m14.size_of(ops) + - self.m21.size_of(ops) + - self.m22.size_of(ops) + - self.m23.size_of(ops) + - self.m24.size_of(ops) + - self.m31.size_of(ops) + - self.m32.size_of(ops) + - self.m33.size_of(ops) + - self.m34.size_of(ops) + - self.m41.size_of(ops) + - self.m42.size_of(ops) + - self.m43.size_of(ops) + - self.m44.size_of(ops) - } -} - -impl MallocSizeOf for euclid::TypedVector2D { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.x.size_of(ops) + self.y.size_of(ops) - } -} - -impl MallocSizeOf for Void { - #[inline] - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - void::unreachable(*self) - } -} - -#[cfg(feature = "servo")] -impl MallocSizeOf for string_cache::Atom { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - 0 - } -} - -/// For use on types where size_of() returns 0. -#[macro_export] -macro_rules! malloc_size_of_is_0( - ($($ty:ty),+) => ( - $( - impl $crate::MallocSizeOf for $ty { - #[inline(always)] - fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize { - 0 - } - } - )+ - ); - ($($ty:ident<$($gen:ident),+>),+) => ( - $( - impl<$($gen: $crate::MallocSizeOf),+> $crate::MallocSizeOf for $ty<$($gen),+> { - #[inline(always)] - fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize { - 0 - } - } - )+ - ); -); - -malloc_size_of_is_0!(bool, char, str); -malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize); -malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize); -malloc_size_of_is_0!(f32, f64); - -malloc_size_of_is_0!(std::sync::atomic::AtomicBool); -malloc_size_of_is_0!(std::sync::atomic::AtomicIsize); -malloc_size_of_is_0!(std::sync::atomic::AtomicUsize); - -malloc_size_of_is_0!(Range, Range, Range, Range, Range); -malloc_size_of_is_0!(Range, Range, Range, Range, Range); -malloc_size_of_is_0!(Range, Range); - -malloc_size_of_is_0!(app_units::Au); - -malloc_size_of_is_0!(cssparser::RGBA, cssparser::TokenSerializationType); - -#[cfg(feature = "url")] -impl MallocSizeOf for url::Host { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - match *self { - url::Host::Domain(ref s) => s.size_of(ops), - _ => 0, - } - } -} -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::BorderRadius); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::BorderStyle); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::BoxShadowClipMode); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ColorF); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ComplexClipRegion); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ExtendMode); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::FilterOp); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ExternalScrollId); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::FontInstanceKey); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::GradientStop); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::GlyphInstance); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::NinePatchBorder); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ImageKey); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ImageRendering); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::LineStyle); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::MixBlendMode); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::NormalBorder); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::RepeatMode); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::ScrollSensitivity); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::StickyOffsetBounds); -#[cfg(feature = "webrender_api")] -malloc_size_of_is_0!(webrender_api::TransformStyle); - -#[cfg(feature = "servo")] -impl MallocSizeOf for keyboard_types::Key { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - match self { - keyboard_types::Key::Character(ref s) => s.size_of(ops), - _ => 0, - } - } -} - -#[cfg(feature = "servo")] -malloc_size_of_is_0!(keyboard_types::Modifiers); - -#[cfg(feature = "servo")] -impl MallocSizeOf for xml5ever::QualName { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.prefix.size_of(ops) + self.ns.size_of(ops) + self.local.size_of(ops) - } -} - -#[cfg(feature = "servo")] -malloc_size_of_is_0!(time::Duration); -#[cfg(feature = "servo")] -malloc_size_of_is_0!(time::Tm); - -#[cfg(feature = "servo")] -impl MallocSizeOf for hyper_serde::Serde -where - for<'de> hyper_serde::De: 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! -#[cfg(feature = "servo")] -impl MallocSizeOf for crossbeam_channel::Sender { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - 0 - } -} - -#[cfg(feature = "servo")] -impl MallocSizeOf for hyper::StatusCode { - fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - 0 - } -} - -/// Measurable that defers to inner value and used to verify MallocSizeOf implementation in a -/// struct. -#[derive(Clone)] -pub struct Measurable(pub T); - -impl Deref for Measurable { - type Target = T; - - fn deref(&self) -> &T { - &self.0 - } -} - -impl DerefMut for Measurable { - fn deref_mut(&mut self) -> &mut T { - &mut self.0 - } -} \ No newline at end of file diff --git a/src/bin/drawing/painter.rs b/src/bin/drawing/painter.rs index d000962..45fd263 100644 --- a/src/bin/drawing/painter.rs +++ b/src/bin/drawing/painter.rs @@ -781,9 +781,6 @@ impl Painter { hud.paint( app_state, &self.window, - app_state.screen.width as f64, - app_state.screen.height as f64, - self.hidpi_factor, &mut self.device, &mut encoder, &frame.view, diff --git a/src/bin/drawing/ui.rs b/src/bin/drawing/ui.rs index 55637c5..62acd90 100644 --- a/src/bin/drawing/ui.rs +++ b/src/bin/drawing/ui.rs @@ -69,9 +69,6 @@ impl HUD { &mut self, app_state: &mut AppState, window: &winit::window::Window, - width: f64, - height: f64, - hidpi_factor: f64, device: &mut wgpu::Device, encoder: &mut wgpu::CommandEncoder, view: &wgpu::TextureView, @@ -206,7 +203,7 @@ impl HUD { self.platform.prepare_render(&ui, &window); self.renderer - .render(ui, width, height, hidpi_factor, device, encoder, &view) + .render(ui, device, encoder, &view) .expect("Rendering failed"); } diff --git a/src/lib/css.rs b/src/lib/css.rs index ed044d8..9e4a6b7 100644 --- a/src/lib/css.rs +++ b/src/lib/css.rs @@ -304,6 +304,11 @@ impl Selector { true } + + pub fn size(&self) -> usize { + use parity_util_mem::MallocSizeOfExt; + std::mem::size_of::() + self.malloc_size_of() + } } // impl wr_malloc_size_of::MallocSizeOf for Selector { @@ -576,4 +581,10 @@ fn rgb_color<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, CSS ))(input)?; let (input, _) = tag(")")(input)?; Ok((input, CSSValue::Color(Color { r: r as f32 / 255.0, g: g as f32 / 255.0, b: b as f32 / 255.0, a: 1.0 }))) +} + +#[test] +fn selector_size() { + let selector = super::Selector::default(); + assert_eq!(selector.size(), 42); } \ No newline at end of file diff --git a/src/lib/object.rs b/src/lib/object.rs index 60eb4dd..4a068de 100644 --- a/src/lib/object.rs +++ b/src/lib/object.rs @@ -59,9 +59,10 @@ impl Object { pub fn size(&self) -> usize { use parity_util_mem::MallocSizeOfExt; - self.selector.malloc_size_of() - + self.tags.malloc_size_of() - + self.points.len() * std::mem::size_of::() + 8 + self.selector.size() + + self.tags.malloc_size_of() + std::mem::size_of_val(&self.tags) + + self.tags.iter().map(|(k, v)| k.len() + v.len()).sum::() + + self.points.capacity() * std::mem::size_of::() + 8 + std::mem::size_of::() } } \ No newline at end of file diff --git a/src/lib/vector_tile/tile.rs b/src/lib/vector_tile/tile.rs index de3e94e..5409711 100644 --- a/src/lib/vector_tile/tile.rs +++ b/src/lib/vector_tile/tile.rs @@ -24,17 +24,18 @@ use lyon::{ }; use crate::*; -fn format_size(value: usize) -> String { - format!("{:.10}B", size_format::SizeFormatterSI::new(value as u64)) +fn format_size(value: &usize, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:.1}B", size_format::SizeFormatterSI::new(*value as u64)) } -#[derive(Debug, Clone, Copy, Derivative)] +#[derive(Clone, Copy, Derivative)] +#[derivative(Debug)] pub struct TileStats { pub objects: usize, pub features: usize, pub vertices: usize, pub indices: usize, - #[derivative(Debug(format_with="::format_size"))] + #[derivative(Debug(format_with="format_size"))] pub size: usize, } @@ -217,17 +218,17 @@ impl Tile { let vertex_size = std::mem::size_of::(); let index_size = std::mem::size_of::(); - TileStats { + dbg!(TileStats { objects: objects.len(), features: features.len(), vertices: mesh.vertices.len(), indices: mesh.indices.len(), size: objects.iter().map(|o| o.size()).sum::() - + features.len() * feature_size - + mesh.vertices.len() * vertex_size - + mesh.indices.len() * index_size, - } + + features.capacity() * feature_size + + mesh.vertices.capacity() * vertex_size + + mesh.indices.capacity() * index_size, + }) }; spawn(move|| {