diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 9d2c3c46848..45f74b3185b 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -219,7 +219,6 @@ impl DisplayList { } } -// FIXME(njn): other fields may be measured later, esp. `layer` #[derive(HeapSizeOf)] /// Represents one CSS stacking context, which may or may not have a hardware layer. pub struct StackingContext { @@ -227,7 +226,7 @@ pub struct StackingContext { pub display_list: Box, /// The layer for this stacking context, if there is one. - #[ignore_heap_size] + #[ignore_heap_size_of = "FIXME(njn): should measure this at some point"] pub layer: Option>, /// The position and size of this stacking context. @@ -240,11 +239,9 @@ pub struct StackingContext { pub z_index: i32, /// CSS filters to be applied to this stacking context (including opacity). - #[ignore_heap_size] pub filters: filter::T, /// The blend mode with which this stacking context blends with its backdrop. - #[ignore_heap_size] pub blend_mode: mix_blend_mode::T, /// A transform to be applied to this stacking context. @@ -768,7 +765,6 @@ pub struct DisplayItemMetadata { pub node: OpaqueNode, /// The value of the `cursor` property when the mouse hovers over this display item. If `None`, /// this display item is ineligible for pointer events (`pointer-events: none`). - #[ignore_heap_size] pub pointing: Option, } @@ -808,7 +804,7 @@ pub struct TextDisplayItem { pub base: BaseDisplayItem, /// The text run. - #[ignore_heap_size] // We exclude `text_run` because it is non-owning. + #[ignore_heap_size_of = "Because it is non-owning"] pub text_run: Arc>, /// The range of text within the text run. @@ -838,7 +834,7 @@ pub enum TextOrientation { #[derive(Clone, HeapSizeOf)] pub struct ImageDisplayItem { pub base: BaseDisplayItem, - #[ignore_heap_size] // We exclude `image` here because it is non-owning. + #[ignore_heap_size_of = "Because it is non-owning"] pub image: Arc, /// The dimensions to which the image display item should be stretched. If this is smaller than @@ -848,7 +844,6 @@ pub struct ImageDisplayItem { /// The algorithm we should use to stretch the image. See `image_rendering` in CSS-IMAGES-3 ยง /// 5.3. - #[ignore_heap_size] pub image_rendering: image_rendering::T, } diff --git a/components/plugins/heap_size.rs b/components/plugins/heap_size.rs new file mode 100644 index 00000000000..c59a89b8904 --- /dev/null +++ b/components/plugins/heap_size.rs @@ -0,0 +1,81 @@ +/* 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/. */ + +//! Handles the auto-deriving for `#[derive(HeapSizeOf)]` +//! +//! This provides the `#[derive(HeapSizeOf)]` decorator, which +//! generates a `HeapSizeOf` implementation that adds up +//! calls to heap_size_of_children() for all the fields +//! of a struct or enum variant. +//! +//! Fields marked `#[ignore_heap_size_of = "reason"]` will +//! be ignored in this calculation. Providing a reason is compulsory. + + +use syntax::ext::base::{Annotatable, ExtCtxt}; +use syntax::codemap::Span; +use syntax::ptr::P; +use syntax::ast::*; +use syntax::attr::AttrMetaMethods; +use syntax::ext::build::AstBuilder; +use syntax::ext::deriving::generic::*; + +pub fn expand_heap_size(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, + item: Annotatable, push: &mut FnMut(Annotatable)) { + let trait_def = TraitDef { + span: span, + attributes: Vec::new(), + path: ty::Path::new(vec!("util", "mem", "HeapSizeOf")), + additional_bounds: Vec::new(), + generics: ty::LifetimeBounds::empty(), + methods: vec![ + MethodDef { + name: "heap_size_of_children", + generics: ty::LifetimeBounds::empty(), + explicit_self: ty::borrowed_explicit_self(), + args: vec!(), + ret_ty: ty::Literal(ty::Path::new_local("usize")), + attributes: vec!(), + is_unsafe: false, + combine_substructure: combine_substructure(Box::new(heap_size_substructure)) + } + ], + associated_types: vec![], + }; + trait_def.expand(cx, mitem, &item, push) +} + +/// Defines how the implementation for `heap_size_of_children()` is to be generated. +fn heap_size_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { + let fields = match *substr.fields { + Struct(ref fs) | EnumMatching(_, _, ref fs) => fs, + _ => cx.span_bug(trait_span, "impossible substructure in `#[derive(HeapSizeOf)]`") + }; + + fields.iter().fold(cx.expr_usize(trait_span, 0), |acc, ref item| { + if item.attrs.iter() + .find(|ref a| { + if a.check_name("ignore_heap_size_of") { + match a.node.value.node { + MetaNameValue(..) => (), + _ => cx.span_err(a.span, "#[ignore_heap_size_of] \ + should have an explanation, \ + e.g. #[ignore_heap_size_of = \"foo\"]") + } + true + } else { + false + } + }) + .is_some() { + acc + } else { + cx.expr_binary(item.span, BiAdd, acc, + cx.expr_method_call(item.span, + item.self_.clone(), + substr.method_ident, + Vec::new())) + } + }) +} diff --git a/components/plugins/heapsize.rs b/components/plugins/heapsize.rs deleted file mode 100644 index 1a6d27fea22..00000000000 --- a/components/plugins/heapsize.rs +++ /dev/null @@ -1,58 +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/. */ - -use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::codemap::Span; -use syntax::ptr::P; -use syntax::ast::*; -use syntax::attr::AttrMetaMethods; -use syntax::ext::build::AstBuilder; -use syntax::ext::deriving::generic::*; - -pub fn expand_heapsize(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, - item: Annotatable, push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: Vec::new(), - path: ty::Path::new(vec!("util", "mem", "HeapSizeOf")), - additional_bounds: Vec::new(), - generics: ty::LifetimeBounds::empty(), - methods: vec![ - MethodDef { - name: "heap_size_of_children", - generics: ty::LifetimeBounds::empty(), - explicit_self: ty::borrowed_explicit_self(), - args: vec!(), - ret_ty: ty::Literal(ty::Path::new_local("usize")), - attributes: vec!(), - is_unsafe: false, - combine_substructure: combine_substructure(Box::new(heapsize_substructure)) - } - ], - associated_types: vec![], - }; - trait_def.expand(cx, mitem, &item, push) -} - -fn heapsize_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { - let fields = match *substr.fields { - Struct(ref fs) | EnumMatching(_, _, ref fs) => fs, - _ => cx.span_bug(trait_span, "impossible substructure in `heapsize`") - }; - - fields.iter().fold(cx.expr_usize(trait_span, 0), - |acc, ref item| { - if item.attrs.iter() - .find(|ref a| a.check_name("ignore_heap_size")) - .is_some() { - acc - } else { - cx.expr_binary(item.span, BiAdd, acc, - cx.expr_method_call(item.span, - item.self_.clone(), - substr.method_ident, - Vec::new())) - } - }) -} diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index fd8fdd615b7..8f9f698f1d8 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -31,8 +31,8 @@ use syntax::parse::token::intern; // Public for documentation to show up /// Handles the auto-deriving for `#[jstraceable]` pub mod jstraceable; -/// Handles the auto-deriving for `#[heapsize]` -pub mod heapsize; +/// Handles the auto-deriving for `#[derive(HeapSizeOf)]` +pub mod heap_size; /// Autogenerates implementations of Reflectable on DOM structs pub mod reflector; pub mod lints; @@ -45,7 +45,7 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension(intern("dom_struct"), MultiModifier(box jstraceable::expand_dom_struct)); reg.register_syntax_extension(intern("jstraceable"), MultiDecorator(box jstraceable::expand_jstraceable)); reg.register_syntax_extension(intern("_generate_reflector"), MultiDecorator(box reflector::expand_reflector)); - reg.register_syntax_extension(intern("derive_HeapSizeOf"), MultiDecorator(box heapsize::expand_heapsize)); + reg.register_syntax_extension(intern("derive_HeapSizeOf"), MultiDecorator(box heap_size::expand_heap_size)); reg.register_macro("to_lower", casing::expand_lower); reg.register_macro("to_upper", casing::expand_upper); reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject); diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index 0e630183801..fd2267a0a94 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -2935,7 +2935,7 @@ pub mod longhands { use values::CSSFloat; use values::specified::{Angle}; - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, PartialEq, Debug, HeapSizeOf)] pub enum Filter { Blur(Au), Brightness(CSSFloat), @@ -2948,7 +2948,7 @@ pub mod longhands { Sepia(CSSFloat), } - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, PartialEq, Debug, HeapSizeOf)] pub struct T { pub filters: Vec } impl T { @@ -3631,7 +3631,7 @@ pub mod longhands { use cssparser::ToCss; use std::fmt; - #[derive(Copy, Clone, Debug, PartialEq)] + #[derive(Copy, Clone, Debug, PartialEq, HeapSizeOf)] pub enum T { Auto, CrispEdges, diff --git a/components/style/values.rs b/components/style/values.rs index f1d9a9df9fa..9c74dc47fd4 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -12,7 +12,7 @@ macro_rules! define_css_keyword_enum { }; ($name: ident: $( $css: expr => $variant: ident ),+) => { #[allow(non_camel_case_types)] - #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug)] + #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug, HeapSizeOf)] pub enum $name { $( $variant ),+ } @@ -68,7 +68,6 @@ macro_rules! define_numbered_css_keyword_enum { } } - pub type CSSFloat = f32; @@ -607,7 +606,7 @@ pub mod specified { } } - #[derive(Clone, PartialEq, PartialOrd, Copy, Debug)] + #[derive(Clone, PartialEq, PartialOrd, Copy, Debug, HeapSizeOf)] pub struct Angle(pub CSSFloat); impl ToCss for Angle { diff --git a/components/util/mem.rs b/components/util/mem.rs index 3575627d46a..5043fea7d93 100644 --- a/components/util/mem.rs +++ b/components/util/mem.rs @@ -9,11 +9,12 @@ use std::collections::LinkedList; use std::mem::transmute; use std::sync::Arc; -use geom::{Point2D, Rect, SideOffsets2D, Size2D, Matrix2D}; +use azure::azure_hl::Color; +use cursor::Cursor; +use geom::{Point2D, Rect, SideOffsets2D, Size2D, Matrix2D}; use geometry::Au; use range::Range; -use azure::azure_hl::Color; extern { // Get the size of a heap block. @@ -41,9 +42,6 @@ pub fn heap_size_of(ptr: *const c_void) -> usize { // return multiple measurements -- e.g. measure text separately from images -- are also possible, // and should be used when appropriate. // -// FIXME(njn): it would be nice to be able to derive this trait automatically, given that -// implementations are mostly repetitive and mechanical. -// 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:: measures, more or less); that @@ -165,7 +163,7 @@ impl Drop for LinkedList2 { } /// For use on types defined in external crates -/// with known heap sizes +/// with known heap sizes. #[macro_export] macro_rules! known_heap_size( ($size:expr, $($ty:ident),+) => ( @@ -197,5 +195,5 @@ known_heap_size!(0, bool, f32, f64); known_heap_size!(0, Rect, Point2D, Size2D, Matrix2D, SideOffsets2D); -known_heap_size!(0, Au, Color); +known_heap_size!(0, Au, Color, Cursor); known_heap_size!(0, Range);