mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Add #[heapsize]/#[derive(HeapSizeOf)] plugin to auto-derive HeapSizeOf
impls
(fixes #5914)
This commit is contained in:
parent
05212b702d
commit
f4bc92526a
3 changed files with 87 additions and 2 deletions
54
components/plugins/heapsize.rs
Normal file
54
components/plugins/heapsize.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
|
||||||
|
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<Expr> {
|
||||||
|
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_heapsize"))
|
||||||
|
.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()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -8,8 +8,7 @@
|
||||||
//!
|
//!
|
||||||
//! - `#[privatize]` : Forces all fields in a struct/enum to be private
|
//! - `#[privatize]` : Forces all fields in a struct/enum to be private
|
||||||
//! - `#[jstraceable]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
|
//! - `#[jstraceable]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
|
||||||
//! - `#[must_root]` : Prevents data of the marked type from being used on the stack. See the lints module for more
|
//! - `#[must_root]` : Prevents data of the marked type from being used on the stack. See the lints module for more details
|
||||||
//! details
|
|
||||||
//! - `#[dom_struct]` : Implies `#[privatize]`,`#[jstraceable]`, and `#[must_root]`.
|
//! - `#[dom_struct]` : Implies `#[privatize]`,`#[jstraceable]`, and `#[must_root]`.
|
||||||
//! Use this for structs that correspond to a DOM type
|
//! Use this for structs that correspond to a DOM type
|
||||||
|
|
||||||
|
@ -31,6 +30,8 @@ use syntax::parse::token::intern;
|
||||||
// Public for documentation to show up
|
// Public for documentation to show up
|
||||||
/// Handles the auto-deriving for `#[jstraceable]`
|
/// Handles the auto-deriving for `#[jstraceable]`
|
||||||
pub mod jstraceable;
|
pub mod jstraceable;
|
||||||
|
/// Handles the auto-deriving for `#[heapsize]`
|
||||||
|
pub mod heapsize;
|
||||||
/// Autogenerates implementations of Reflectable on DOM structs
|
/// Autogenerates implementations of Reflectable on DOM structs
|
||||||
pub mod reflector;
|
pub mod reflector;
|
||||||
pub mod lints;
|
pub mod lints;
|
||||||
|
@ -43,6 +44,8 @@ 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("dom_struct"), MultiModifier(box jstraceable::expand_dom_struct));
|
||||||
reg.register_syntax_extension(intern("jstraceable"), MultiDecorator(box jstraceable::expand_jstraceable));
|
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("_generate_reflector"), MultiDecorator(box reflector::expand_reflector));
|
||||||
|
reg.register_syntax_extension(intern("derive_HeapSizeOf"), MultiDecorator(box heapsize::expand_heapsize));
|
||||||
|
reg.register_syntax_extension(intern("heapsize"), MultiDecorator(box heapsize::expand_heapsize));
|
||||||
reg.register_macro("to_lower", casing::expand_lower);
|
reg.register_macro("to_lower", casing::expand_lower);
|
||||||
reg.register_macro("to_upper", casing::expand_upper);
|
reg.register_macro("to_upper", casing::expand_upper);
|
||||||
reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject);
|
reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject);
|
||||||
|
|
|
@ -158,3 +158,31 @@ impl<T> Drop for LinkedList2<T> {
|
||||||
fn drop(&mut self) {}
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For use on types defined in external crates
|
||||||
|
/// with known heap sizes
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! known_heap_size(
|
||||||
|
($size:expr, $($ty:ident),+) => (
|
||||||
|
$(
|
||||||
|
impl $crate::mem::HeapSizeOf for $ty {
|
||||||
|
#[inline]
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
$size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
);
|
||||||
|
($size: expr, $ty:ident<$($gen:ident),+>) => (
|
||||||
|
impl<$($gen),+> $crate::mem::HeapSizeOf for $ty<$($gen),+> {
|
||||||
|
#[inline]
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
$size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
known_heap_size!(0, u8, u16, u32, u64, usize);
|
||||||
|
known_heap_size!(0, i8, i16, i32, i64, isize);
|
||||||
|
known_heap_size!(0, bool);
|
Loading…
Add table
Add a link
Reference in a new issue