Repository: servo/servo
File: components/malloc_size_of/lib.rs (Rust)

Code before:
impl MallocSizeOf for usvg::Tree {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let root = self.root();
        let linear_gradients = self.linear_gradients();
        let radial_gradients = self.radial_gradients();
        let patterns = self.patterns();
        let clip_paths = self.clip_paths();
        let masks = self.masks();
        let filters = self.filters();
        let fontdb = self.fontdb();

        let mut sum = 0;
        sum += root.size_of(ops);
        sum += linear_gradients
            .iter()
            .map(|x| x.size_of(ops))
            .sum::<usize>();
        sum += radial_gradients
            .iter()
            .map(|x| x.size_of(ops))
            .sum::<usize>();
        sum += patterns.iter().map(|x| x.size_of(ops)).sum::<usize>();
        sum += clip_paths.iter().map(|x| x.size_of(ops)).sum::<usize>();
        sum += masks.iter().map(|x| x.size_of(ops)).sum::<usize>();
        sum += filters.iter().map(|x| x.size_of(ops)).sum::<usize>();
        sum += fontdb.size_of(ops);

        if ops.has_malloc_enclosing_size_of() {
            unsafe {
                sum += ops.malloc_enclosing_size_of(root);
                if !linear_gradients.is_empty() {
                    sum += ops.malloc_enclosing_size_of(linear_gradients.as_ptr());
                }
                if !radial_gradients.is_empty() {
                    sum += ops.malloc_enclosing_size_of(radial_gradients.as_ptr());
                }
                if !patterns.is_empty() {
                    sum += ops.malloc_enclosing_size_of(patterns.as_ptr());
                }
                if !clip_paths.is_empty() {
                    sum += ops.malloc_enclosing_size_of(clip_paths.as_ptr());
                }
                if !masks.is_empty() {
                    sum += ops.malloc_enclosing_size_of(masks.as_ptr());
                }
                if !filters.is_empty() {
                    sum += ops.malloc_enclosing_size_of(filters.as_ptr());
                }
                sum += ops.malloc_enclosing_size_of(fontdb);
            }
        }

Review comment (bug):
This is subtle, but `fontdb.size_of(ops)` is doing the wrong thing here, since `fontdb` is a `&Arc<FontDb>` (https://doc.servo.org/src/servo_malloc_size_of/lib.rs.html#175-180). Instead, we need `fontdb.conditional_size_of(ops)`.

Code after:
impl MallocSizeOf for usvg::Tree {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let root = self.root();
        let linear_gradients = self.linear_gradients();
        let radial_gradients = self.radial_gradients();
        let patterns = self.patterns();
        let clip_paths = self.clip_paths();
        let masks = self.masks();
        let filters = self.filters();
        let fontdb = self.fontdb();

        let mut sum = root.size_of(ops) +
            linear_gradients.size_of(ops) +
            radial_gradients.size_of(ops) +
            patterns.size_of(ops) +
            clip_paths.size_of(ops) +
            masks.size_of(ops) +
            filters.size_of(ops);

        sum += fontdb.conditional_size_of(ops);

        if ops.has_malloc_enclosing_size_of() {
            unsafe {
                sum += ops.malloc_enclosing_size_of(root);
                if !linear_gradients.is_empty() {
                    sum += ops.malloc_enclosing_size_of(linear_gradients.as_ptr());
                }
                if !radial_gradients.is_empty() {
                    sum += ops.malloc_enclosing_size_of(radial_gradients.as_ptr());
                }
                if !patterns.is_empty() {
                    sum += ops.malloc_enclosing_size_of(patterns.as_ptr());
                }
                if !clip_paths.is_empty() {
                    sum += ops.malloc_enclosing_size_of(clip_paths.as_ptr());
                }
                if !masks.is_empty() {
                    sum += ops.malloc_enclosing_size_of(masks.as_ptr());
                }
                if !filters.is_empty() {
                    sum += ops.malloc_enclosing_size_of(filters.as_ptr());
                }
            }
        }
        sum
    }
}

impl MallocSizeOf for usvg::Group {
    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
        let id = self.id();