1use std::cell::OnceCell;
50use std::collections::BinaryHeap;
51use std::hash::{BuildHasher, Hash};
52use std::ops::Range;
53use std::rc::Rc;
54use std::sync::{Arc, OnceLock};
55
56use resvg::usvg::fontdb::Source;
57use resvg::usvg::{self, tiny_skia_path};
58use style::properties::ComputedValues;
59use style::values::generics::length::GenericLengthPercentageOrAuto;
60pub use stylo_malloc_size_of::MallocSizeOfOps;
61use uuid::Uuid;
62
63pub trait MallocSizeOf {
66 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
69}
70
71pub trait MallocShallowSizeOf {
73 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
78}
79
80pub trait MallocUnconditionalSizeOf {
84 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
87}
88
89pub trait MallocUnconditionalShallowSizeOf {
91 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
93}
94
95pub trait MallocConditionalSizeOf {
99 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
103}
104
105pub trait MallocConditionalShallowSizeOf {
107 fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
109}
110
111impl<T: MallocSizeOf> MallocSizeOf for [T] {
112 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
113 let mut n = 0;
114 for elem in self.iter() {
115 n += elem.size_of(ops);
116 }
117 n
118 }
119}
120
121impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for [T] {
122 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
123 self.iter()
124 .map(|element| element.conditional_size_of(ops))
125 .sum()
126 }
127}
128
129#[macro_export]
131macro_rules! malloc_size_of_is_0(
132 ($($ty:ty),+) => (
133 $(
134 impl $crate::MallocSizeOf for $ty {
135 #[inline(always)]
136 fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
137 0
138 }
139 }
140 )+
141 );
142 ($($ty:ident<$($gen:ident),+>),+) => (
143 $(
144 impl<$($gen: $crate::MallocSizeOf),+> $crate::MallocSizeOf for $ty<$($gen),+> {
145 #[inline(always)]
146 fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
147 0
148 }
149 }
150 )+
151 );
152);
153
154impl MallocSizeOf for keyboard_types::Key {
155 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
156 match &self {
157 keyboard_types::Key::Character(string) => {
158 <String as MallocSizeOf>::size_of(string, ops)
159 },
160 _ => 0,
161 }
162 }
163}
164
165impl MallocSizeOf for markup5ever::QualName {
166 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
167 self.prefix.size_of(ops) + self.ns.size_of(ops) + self.local.size_of(ops)
168 }
169}
170
171impl MallocSizeOf for String {
172 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
173 unsafe { ops.malloc_size_of(self.as_ptr()) }
174 }
175}
176
177impl<T: ?Sized> MallocSizeOf for &'_ T {
178 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
179 0
181 }
182}
183
184impl<T: ?Sized> MallocShallowSizeOf for Box<T> {
185 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
186 unsafe { ops.malloc_size_of(&**self) }
187 }
188}
189
190impl<T: MallocSizeOf + ?Sized> MallocSizeOf for Box<T> {
191 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
192 self.shallow_size_of(ops) + (**self).size_of(ops)
193 }
194}
195
196impl MallocSizeOf for () {
197 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
198 0
199 }
200}
201
202impl<T1, T2> MallocSizeOf for (T1, T2)
203where
204 T1: MallocSizeOf,
205 T2: MallocSizeOf,
206{
207 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
208 self.0.size_of(ops) + self.1.size_of(ops)
209 }
210}
211
212impl<T1, T2, T3> MallocSizeOf for (T1, T2, T3)
213where
214 T1: MallocSizeOf,
215 T2: MallocSizeOf,
216 T3: MallocSizeOf,
217{
218 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
219 self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops)
220 }
221}
222
223impl<T1, T2, T3, T4> MallocSizeOf for (T1, T2, T3, T4)
224where
225 T1: MallocSizeOf,
226 T2: MallocSizeOf,
227 T3: MallocSizeOf,
228 T4: MallocSizeOf,
229{
230 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
231 self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) + self.3.size_of(ops)
232 }
233}
234
235impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for Option<T> {
236 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
237 if let Some(val) = self.as_ref() {
238 val.conditional_size_of(ops)
239 } else {
240 0
241 }
242 }
243}
244
245impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for Vec<T> {
246 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
247 let mut n = self.shallow_size_of(ops);
248 for elem in self.iter() {
249 n += elem.conditional_size_of(ops);
250 }
251 n
252 }
253}
254
255impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for std::collections::VecDeque<T> {
256 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
257 let mut n = self.shallow_size_of(ops);
258 for elem in self.iter() {
259 n += elem.conditional_size_of(ops);
260 }
261 n
262 }
263}
264
265impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for std::cell::RefCell<T> {
266 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
267 self.borrow().conditional_size_of(ops)
268 }
269}
270
271impl<T1, T2> MallocConditionalSizeOf for (T1, T2)
272where
273 T1: MallocConditionalSizeOf,
274 T2: MallocConditionalSizeOf,
275{
276 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
277 self.0.conditional_size_of(ops) + self.1.conditional_size_of(ops)
278 }
279}
280
281impl<T: MallocConditionalSizeOf + ?Sized> MallocConditionalSizeOf for Box<T> {
282 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
283 self.shallow_size_of(ops) + (**self).conditional_size_of(ops)
284 }
285}
286
287impl<T: MallocConditionalSizeOf, E: MallocSizeOf> MallocConditionalSizeOf for Result<T, E> {
288 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
289 match *self {
290 Ok(ref x) => x.conditional_size_of(ops),
291 Err(ref e) => e.size_of(ops),
292 }
293 }
294}
295
296impl MallocConditionalSizeOf for () {
297 fn conditional_size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
298 0
299 }
300}
301
302impl<T: MallocSizeOf> MallocSizeOf for Option<T> {
303 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
304 if let Some(val) = self.as_ref() {
305 val.size_of(ops)
306 } else {
307 0
308 }
309 }
310}
311
312impl<T: MallocSizeOf, E: MallocSizeOf> MallocSizeOf for Result<T, E> {
313 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
314 match *self {
315 Ok(ref x) => x.size_of(ops),
316 Err(ref e) => e.size_of(ops),
317 }
318 }
319}
320
321impl<T: MallocSizeOf + Copy> MallocSizeOf for std::cell::Cell<T> {
322 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
323 self.get().size_of(ops)
324 }
325}
326
327impl<T: MallocSizeOf> MallocSizeOf for std::cell::RefCell<T> {
328 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
329 self.borrow().size_of(ops)
330 }
331}
332
333impl<B: ?Sized + ToOwned> MallocSizeOf for std::borrow::Cow<'_, B>
334where
335 B::Owned: MallocSizeOf,
336{
337 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
338 match *self {
339 std::borrow::Cow::Borrowed(_) => 0,
340 std::borrow::Cow::Owned(ref b) => b.size_of(ops),
341 }
342 }
343}
344
345impl<T> MallocShallowSizeOf for Vec<T> {
346 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
347 unsafe { ops.malloc_size_of(self.as_ptr()) }
348 }
349}
350
351impl<T: MallocSizeOf> MallocSizeOf for Vec<T> {
352 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
353 let mut n = self.shallow_size_of(ops);
354 for elem in self.iter() {
355 n += elem.size_of(ops);
356 }
357 n
358 }
359}
360
361impl<T> MallocShallowSizeOf for std::collections::VecDeque<T> {
362 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
363 if ops.has_malloc_enclosing_size_of() {
364 if let Some(front) = self.front() {
365 unsafe { ops.malloc_enclosing_size_of(front) }
367 } else {
368 0
370 }
371 } else {
372 self.capacity() * size_of::<T>()
374 }
375 }
376}
377
378impl<T: MallocSizeOf> MallocSizeOf for std::collections::VecDeque<T> {
379 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
380 let mut n = self.shallow_size_of(ops);
381 for elem in self.iter() {
382 n += elem.size_of(ops);
383 }
384 n
385 }
386}
387
388impl<A: smallvec::Array> MallocShallowSizeOf for smallvec::SmallVec<A> {
389 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
390 if self.spilled() {
391 unsafe { ops.malloc_size_of(self.as_ptr()) }
392 } else {
393 0
394 }
395 }
396}
397
398impl<A> MallocSizeOf for smallvec::SmallVec<A>
399where
400 A: smallvec::Array,
401 A::Item: MallocSizeOf,
402{
403 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
404 let mut n = self.shallow_size_of(ops);
405 for elem in self.iter() {
406 n += elem.size_of(ops);
407 }
408 n
409 }
410}
411
412impl<A: MallocConditionalSizeOf> MallocConditionalSizeOf for smallvec::SmallVec<A>
413where
414 A: smallvec::Array,
415 A::Item: MallocConditionalSizeOf,
416{
417 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
418 if !self.spilled() {
419 return 0;
420 }
421
422 self.shallow_size_of(ops) +
423 self.iter()
424 .map(|element| element.conditional_size_of(ops))
425 .sum::<usize>()
426 }
427}
428
429impl<T: MallocSizeOf> MallocSizeOf for BinaryHeap<T> {
430 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
431 self.iter().map(|element| element.size_of(ops)).sum()
432 }
433}
434
435impl<T: MallocSizeOf> MallocSizeOf for Range<T> {
436 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
437 self.start.size_of(ops) + self.end.size_of(ops)
438 }
439}
440
441macro_rules! malloc_size_of_hash_set {
442 ($ty:ty) => {
443 impl<T, S> MallocShallowSizeOf for $ty
444 where
445 T: Eq + Hash,
446 S: BuildHasher,
447 {
448 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
449 if ops.has_malloc_enclosing_size_of() {
450 self.iter()
455 .next()
456 .map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
457 } else {
458 self.capacity() * (size_of::<T>() + size_of::<usize>())
460 }
461 }
462 }
463
464 impl<T, S> MallocSizeOf for $ty
465 where
466 T: Eq + Hash + MallocSizeOf,
467 S: BuildHasher,
468 {
469 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
470 let mut n = self.shallow_size_of(ops);
471 for t in self.iter() {
472 n += t.size_of(ops);
473 }
474 n
475 }
476 }
477 };
478}
479
480malloc_size_of_hash_set!(std::collections::HashSet<T, S>);
481
482macro_rules! malloc_size_of_hash_map {
483 ($ty:ty) => {
484 impl<K, V, S> MallocShallowSizeOf for $ty
485 where
486 K: Eq + Hash,
487 S: BuildHasher,
488 {
489 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
490 if ops.has_malloc_enclosing_size_of() {
492 self.values()
493 .next()
494 .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
495 } else {
496 self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
497 }
498 }
499 }
500
501 impl<K, V, S> MallocSizeOf for $ty
502 where
503 K: Eq + Hash + MallocSizeOf,
504 V: MallocSizeOf,
505 S: BuildHasher,
506 {
507 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
508 let mut n = self.shallow_size_of(ops);
509 for (k, v) in self.iter() {
510 n += k.size_of(ops);
511 n += v.size_of(ops);
512 }
513 n
514 }
515 }
516
517 impl<K, V, S> MallocConditionalSizeOf for $ty
518 where
519 K: Eq + Hash + MallocSizeOf,
520 V: MallocConditionalSizeOf,
521 S: BuildHasher,
522 {
523 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
524 let mut n = self.shallow_size_of(ops);
525 for (k, v) in self.iter() {
526 n += k.size_of(ops);
527 n += v.conditional_size_of(ops);
528 }
529 n
530 }
531 }
532 };
533}
534
535malloc_size_of_hash_map!(std::collections::HashMap<K, V, S>);
536
537impl<K, V> MallocShallowSizeOf for std::collections::BTreeMap<K, V>
538where
539 K: Eq + Hash,
540{
541 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
542 if ops.has_malloc_enclosing_size_of() {
543 self.values()
544 .next()
545 .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
546 } else {
547 self.len() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
548 }
549 }
550}
551
552impl<K, V> MallocSizeOf for std::collections::BTreeMap<K, V>
553where
554 K: Eq + Hash + MallocSizeOf,
555 V: MallocSizeOf,
556{
557 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
558 let mut n = self.shallow_size_of(ops);
559 for (k, v) in self.iter() {
560 n += k.size_of(ops);
561 n += v.size_of(ops);
562 }
563 n
564 }
565}
566
567impl<T> MallocSizeOf for std::marker::PhantomData<T> {
569 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
570 0
571 }
572}
573
574impl<T: MallocSizeOf> MallocSizeOf for OnceCell<T> {
575 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
576 self.get()
577 .map(|interior| interior.size_of(ops))
578 .unwrap_or_default()
579 }
580}
581
582impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for OnceCell<T> {
583 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
584 self.get()
585 .map(|interior| interior.conditional_size_of(ops))
586 .unwrap_or_default()
587 }
588}
589
590impl<T: MallocSizeOf> MallocSizeOf for OnceLock<T> {
591 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
592 self.get()
593 .map(|interior| interior.size_of(ops))
594 .unwrap_or_default()
595 }
596}
597
598impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for OnceLock<T> {
599 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
600 self.get()
601 .map(|interior| interior.conditional_size_of(ops))
602 .unwrap_or_default()
603 }
604}
605
606impl<T> MallocUnconditionalShallowSizeOf for servo_arc::Arc<T> {
614 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
615 unsafe { ops.malloc_size_of(self.heap_ptr()) }
616 }
617}
618
619impl<T: MallocSizeOf> MallocUnconditionalSizeOf for servo_arc::Arc<T> {
620 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
621 self.unconditional_shallow_size_of(ops) + (**self).size_of(ops)
622 }
623}
624
625impl<T> MallocConditionalShallowSizeOf for servo_arc::Arc<T> {
626 fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
627 if ops.have_seen_ptr(self.heap_ptr()) {
628 0
629 } else {
630 self.unconditional_shallow_size_of(ops)
631 }
632 }
633}
634
635impl<T: MallocSizeOf> MallocConditionalSizeOf for servo_arc::Arc<T> {
636 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
637 if ops.have_seen_ptr(self.heap_ptr()) {
638 0
639 } else {
640 self.unconditional_size_of(ops)
641 }
642 }
643}
644
645impl<T> MallocUnconditionalShallowSizeOf for Arc<T> {
646 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
647 unsafe { ops.malloc_size_of(Arc::as_ptr(self)) }
648 }
649}
650
651impl<T: MallocSizeOf> MallocUnconditionalSizeOf for Arc<T> {
652 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
653 self.unconditional_shallow_size_of(ops) + (**self).size_of(ops)
654 }
655}
656
657impl<T> MallocConditionalShallowSizeOf for Arc<T> {
658 fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
659 if ops.have_seen_ptr(Arc::as_ptr(self)) {
660 0
661 } else {
662 self.unconditional_shallow_size_of(ops)
663 }
664 }
665}
666
667impl<T: MallocSizeOf> MallocConditionalSizeOf for Arc<T> {
668 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
669 if ops.have_seen_ptr(Arc::as_ptr(self)) {
670 0
671 } else {
672 self.unconditional_size_of(ops)
673 }
674 }
675}
676
677impl<T> MallocUnconditionalShallowSizeOf for Rc<T> {
678 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
679 unsafe { ops.malloc_size_of(Rc::as_ptr(self)) }
680 }
681}
682
683impl<T: MallocSizeOf> MallocUnconditionalSizeOf for Rc<T> {
684 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
685 self.unconditional_shallow_size_of(ops) + (**self).size_of(ops)
686 }
687}
688
689impl<T: MallocSizeOf> MallocConditionalSizeOf for Rc<T> {
690 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
691 if ops.have_seen_ptr(Rc::as_ptr(self)) {
692 0
693 } else {
694 self.unconditional_size_of(ops)
695 }
696 }
697}
698
699impl<T: MallocSizeOf> MallocSizeOf for std::sync::Mutex<T> {
706 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
707 (*self.lock().unwrap()).size_of(ops)
708 }
709}
710
711impl<T: MallocSizeOf> MallocSizeOf for parking_lot::Mutex<T> {
712 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
713 (*self.lock()).size_of(ops)
714 }
715}
716
717impl<T: MallocSizeOf> MallocSizeOf for parking_lot::RwLock<T> {
718 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
719 (*self.read()).size_of(ops)
720 }
721}
722
723impl<T: MallocConditionalSizeOf> MallocConditionalSizeOf for parking_lot::RwLock<T> {
724 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
725 (*self.read()).conditional_size_of(ops)
726 }
727}
728
729impl<T: MallocSizeOf, Unit> MallocSizeOf for euclid::Length<T, Unit> {
730 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
731 self.0.size_of(ops)
732 }
733}
734
735impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Scale<T, Src, Dst> {
736 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
737 self.0.size_of(ops)
738 }
739}
740
741impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Point2D<T, U> {
742 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
743 self.x.size_of(ops) + self.y.size_of(ops)
744 }
745}
746
747impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Box2D<T, U> {
748 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
749 self.min.size_of(ops) + self.max.size_of(ops)
750 }
751}
752
753impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Rect<T, U> {
754 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
755 self.origin.size_of(ops) + self.size.size_of(ops)
756 }
757}
758
759impl<T: MallocSizeOf, U> MallocSizeOf for euclid::SideOffsets2D<T, U> {
760 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
761 self.top.size_of(ops) +
762 self.right.size_of(ops) +
763 self.bottom.size_of(ops) +
764 self.left.size_of(ops)
765 }
766}
767
768impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Size2D<T, U> {
769 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
770 self.width.size_of(ops) + self.height.size_of(ops)
771 }
772}
773
774impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform2D<T, Src, Dst> {
775 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
776 self.m11.size_of(ops) +
777 self.m12.size_of(ops) +
778 self.m21.size_of(ops) +
779 self.m22.size_of(ops) +
780 self.m31.size_of(ops) +
781 self.m32.size_of(ops)
782 }
783}
784
785impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform3D<T, Src, Dst> {
786 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
787 self.m11.size_of(ops) +
788 self.m12.size_of(ops) +
789 self.m13.size_of(ops) +
790 self.m14.size_of(ops) +
791 self.m21.size_of(ops) +
792 self.m22.size_of(ops) +
793 self.m23.size_of(ops) +
794 self.m24.size_of(ops) +
795 self.m31.size_of(ops) +
796 self.m32.size_of(ops) +
797 self.m33.size_of(ops) +
798 self.m34.size_of(ops) +
799 self.m41.size_of(ops) +
800 self.m42.size_of(ops) +
801 self.m43.size_of(ops) +
802 self.m44.size_of(ops)
803 }
804}
805
806impl MallocSizeOf for url::Host {
807 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
808 match *self {
809 url::Host::Domain(ref s) => s.size_of(ops),
810 _ => 0,
811 }
812 }
813}
814
815impl MallocSizeOf for url::Url {
816 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
817 self.to_string().size_of(ops)
820 }
821}
822
823impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Vector2D<T, U> {
824 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
825 self.x.size_of(ops) + self.y.size_of(ops)
826 }
827}
828
829impl<Static: string_cache::StaticAtomSet> MallocSizeOf for string_cache::Atom<Static> {
830 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
831 0
832 }
833}
834
835impl MallocSizeOf for usvg::Tree {
836 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
837 let root = self.root();
838 let linear_gradients = self.linear_gradients();
839 let radial_gradients = self.radial_gradients();
840 let patterns = self.patterns();
841 let clip_paths = self.clip_paths();
842 let masks = self.masks();
843 let filters = self.filters();
844 let fontdb = self.fontdb();
845
846 let mut sum = root.size_of(ops) +
847 linear_gradients.size_of(ops) +
848 radial_gradients.size_of(ops) +
849 patterns.size_of(ops) +
850 clip_paths.size_of(ops) +
851 masks.size_of(ops) +
852 filters.size_of(ops);
853
854 sum += fontdb.conditional_size_of(ops);
855
856 if ops.has_malloc_enclosing_size_of() {
857 unsafe {
858 sum += ops.malloc_enclosing_size_of(root);
859 if !linear_gradients.is_empty() {
860 sum += ops.malloc_enclosing_size_of(linear_gradients.as_ptr());
861 }
862 if !radial_gradients.is_empty() {
863 sum += ops.malloc_enclosing_size_of(radial_gradients.as_ptr());
864 }
865 if !patterns.is_empty() {
866 sum += ops.malloc_enclosing_size_of(patterns.as_ptr());
867 }
868 if !clip_paths.is_empty() {
869 sum += ops.malloc_enclosing_size_of(clip_paths.as_ptr());
870 }
871 if !masks.is_empty() {
872 sum += ops.malloc_enclosing_size_of(masks.as_ptr());
873 }
874 if !filters.is_empty() {
875 sum += ops.malloc_enclosing_size_of(filters.as_ptr());
876 }
877 }
878 }
879 sum
880 }
881}
882
883impl MallocSizeOf for usvg::Group {
884 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
885 let id = self.id();
886 let children = self.children();
887 let filters = self.filters();
888 let clip_path = self.clip_path();
889
890 let mut sum =
891 id.size_of(ops) + children.size_of(ops) + filters.size_of(ops) + clip_path.size_of(ops);
892
893 if ops.has_malloc_enclosing_size_of() {
894 unsafe {
895 if !id.is_empty() {
896 sum += ops.malloc_enclosing_size_of(id.as_ptr());
897 }
898 if let Some(c) = clip_path {
899 sum += ops.malloc_enclosing_size_of(c)
900 }
901 if !children.is_empty() {
902 sum += ops.malloc_enclosing_size_of(children.as_ptr());
903 }
904 if !filters.is_empty() {
905 sum += ops.malloc_enclosing_size_of(filters.as_ptr());
906 }
907 }
908 }
909 sum
910 }
911}
912
913impl MallocSizeOf for usvg::Node {
914 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
915 let id = self.id();
916
917 let mut sum = id.size_of(ops);
918 if ops.has_malloc_enclosing_size_of() {
919 unsafe {
920 if !id.is_empty() {
921 sum += ops.malloc_enclosing_size_of(id.as_ptr())
922 }
923 }
924 }
925 match self {
926 usvg::Node::Group(group) => {
927 sum += group.size_of(ops);
928 if ops.has_malloc_enclosing_size_of() {
929 unsafe { sum += ops.malloc_enclosing_size_of(group) }
930 }
931 },
932 usvg::Node::Path(path) => {
933 sum += path.size_of(ops);
934 if ops.has_malloc_enclosing_size_of() {
935 unsafe { sum += ops.malloc_enclosing_size_of(path) }
936 }
937 },
938 usvg::Node::Image(image) => {
939 sum += image.size_of(ops);
940 },
941 usvg::Node::Text(text) => {
942 sum += text.size_of(ops);
943 },
944 };
945 sum
946 }
947}
948
949impl MallocSizeOf for usvg::Path {
950 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
951 let id = self.id();
952 let data = self.data();
953 let fill = self.fill();
954 let stroke = self.stroke();
955
956 let mut sum = id.size_of(ops) + data.size_of(ops) + fill.size_of(ops) + stroke.size_of(ops);
957 if ops.has_malloc_enclosing_size_of() {
958 unsafe {
959 if !id.is_empty() {
960 sum += ops.malloc_enclosing_size_of(id.as_ptr());
961 }
962 sum += ops.malloc_enclosing_size_of(data);
963 if let Some(f) = fill {
964 sum += ops.malloc_enclosing_size_of(f)
965 }
966 if let Some(s) = stroke {
967 sum += ops.malloc_enclosing_size_of(s)
968 }
969 }
970 }
971 sum
972 }
973}
974impl MallocSizeOf for tiny_skia_path::Path {
975 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
976 let verbs = self.verbs();
977 let points = self.points();
978
979 let mut sum = verbs.size_of(ops) + points.size_of(ops);
980 if ops.has_malloc_enclosing_size_of() {
981 unsafe {
982 if !points.is_empty() {
983 sum += ops.malloc_enclosing_size_of(points.as_ptr());
984 }
985 if !verbs.is_empty() {
986 sum += ops.malloc_enclosing_size_of(verbs.as_ptr());
987 }
988 }
989 }
990
991 sum
992 }
993}
994
995impl MallocSizeOf for usvg::ClipPath {
996 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
997 let id = self.id();
998 let clip_path = self.clip_path();
999 let root = self.root();
1000
1001 let mut sum = id.size_of(ops) + clip_path.size_of(ops) + root.size_of(ops);
1002 if ops.has_malloc_enclosing_size_of() {
1003 unsafe {
1004 sum += ops.malloc_enclosing_size_of(root);
1005 if !id.is_empty() {
1006 sum += ops.malloc_enclosing_size_of(id.as_ptr());
1007 }
1008 if let Some(c) = clip_path {
1009 sum += c.size_of(ops)
1010 }
1011 }
1012 }
1013 sum
1014 }
1015}
1016
1017impl<T> MallocSizeOf for crossbeam_channel::Sender<T> {
1020 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1021 0
1022 }
1023}
1024
1025impl<T> MallocSizeOf for crossbeam_channel::Receiver<T> {
1026 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1027 0
1028 }
1029}
1030
1031impl<T> MallocSizeOf for tokio::sync::mpsc::UnboundedSender<T> {
1032 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1033 0
1034 }
1035}
1036
1037impl<T> MallocSizeOf for ipc_channel::ipc::IpcSender<T> {
1038 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1039 0
1040 }
1041}
1042
1043impl<T> MallocSizeOf for ipc_channel::ipc::IpcReceiver<T> {
1044 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1045 0
1046 }
1047}
1048
1049impl MallocSizeOf for ipc_channel::ipc::IpcSharedMemory {
1050 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1051 self.len()
1052 }
1053}
1054
1055impl<T: MallocSizeOf> MallocSizeOf for accountable_refcell::RefCell<T> {
1056 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1057 self.borrow().size_of(ops)
1058 }
1059}
1060
1061impl MallocSizeOf for servo_arc::Arc<ComputedValues> {
1062 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1063 self.conditional_size_of(ops)
1064 }
1065}
1066
1067malloc_size_of_hash_map!(indexmap::IndexMap<K, V, S>);
1068malloc_size_of_hash_set!(indexmap::IndexSet<T, S>);
1069
1070malloc_size_of_is_0!(bool, char, str);
1071malloc_size_of_is_0!(f32, f64);
1072malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize);
1073malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize);
1074
1075malloc_size_of_is_0!(Uuid);
1076malloc_size_of_is_0!(app_units::Au);
1077malloc_size_of_is_0!(content_security_policy::Destination);
1078malloc_size_of_is_0!(content_security_policy::sandboxing_directive::SandboxingFlagSet);
1079malloc_size_of_is_0!(http::StatusCode);
1080malloc_size_of_is_0!(keyboard_types::Modifiers);
1081malloc_size_of_is_0!(mime::Mime);
1082malloc_size_of_is_0!(resvg::usvg::fontdb::ID);
1083malloc_size_of_is_0!(resvg::usvg::fontdb::Style);
1084malloc_size_of_is_0!(resvg::usvg::fontdb::Weight);
1085malloc_size_of_is_0!(resvg::usvg::fontdb::Stretch);
1086malloc_size_of_is_0!(resvg::usvg::fontdb::Language);
1087malloc_size_of_is_0!(std::num::NonZeroU16);
1088malloc_size_of_is_0!(std::num::NonZeroU64);
1089malloc_size_of_is_0!(std::num::NonZeroUsize);
1090malloc_size_of_is_0!(std::sync::atomic::AtomicBool);
1091malloc_size_of_is_0!(std::sync::atomic::AtomicIsize);
1092malloc_size_of_is_0!(std::sync::atomic::AtomicUsize);
1093malloc_size_of_is_0!(std::time::Duration);
1094malloc_size_of_is_0!(std::time::Instant);
1095malloc_size_of_is_0!(std::time::SystemTime);
1096malloc_size_of_is_0!(style::data::ElementData);
1097malloc_size_of_is_0!(style::font_face::SourceList);
1098malloc_size_of_is_0!(style::properties::ComputedValues);
1099malloc_size_of_is_0!(style::properties::declaration_block::PropertyDeclarationBlock);
1100malloc_size_of_is_0!(style::queries::values::PrefersColorScheme);
1101malloc_size_of_is_0!(style::stylesheets::Stylesheet);
1102malloc_size_of_is_0!(style::stylesheets::FontFaceRule);
1103malloc_size_of_is_0!(style::values::specified::source_size_list::SourceSizeList);
1104malloc_size_of_is_0!(taffy::Layout);
1105malloc_size_of_is_0!(unicode_bidi::Level);
1106malloc_size_of_is_0!(unicode_script::Script);
1107malloc_size_of_is_0!(urlpattern::UrlPattern);
1108malloc_size_of_is_0!(utf8::Incomplete);
1109
1110impl<S: tendril::TendrilSink<tendril::fmt::UTF8, A>, A: tendril::Atomicity> MallocSizeOf
1111 for tendril::stream::LossyDecoder<S, A>
1112{
1113 fn size_of(&self, _: &mut MallocSizeOfOps) -> usize {
1114 0
1115 }
1116}
1117
1118macro_rules! malloc_size_of_is_webrender_malloc_size_of(
1119 ($($ty:ty),+) => (
1120 $(
1121 impl MallocSizeOf for $ty {
1122 fn size_of(&self, _: &mut MallocSizeOfOps) -> usize {
1123 let mut ops = wr_malloc_size_of::MallocSizeOfOps::new(servo_allocator::usable_size, None);
1124 <$ty as wr_malloc_size_of::MallocSizeOf>::size_of(self, &mut ops)
1125 }
1126 }
1127 )+
1128 );
1129);
1130
1131malloc_size_of_is_webrender_malloc_size_of!(webrender_api::BorderRadius);
1132malloc_size_of_is_webrender_malloc_size_of!(webrender_api::BorderStyle);
1133malloc_size_of_is_webrender_malloc_size_of!(webrender_api::BoxShadowClipMode);
1134malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ColorF);
1135malloc_size_of_is_webrender_malloc_size_of!(webrender_api::Epoch);
1136malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ExtendMode);
1137malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ExternalScrollId);
1138malloc_size_of_is_webrender_malloc_size_of!(webrender_api::FontKey);
1139malloc_size_of_is_webrender_malloc_size_of!(webrender_api::FontInstanceFlags);
1140malloc_size_of_is_webrender_malloc_size_of!(webrender_api::FontInstanceKey);
1141malloc_size_of_is_webrender_malloc_size_of!(webrender_api::GlyphInstance);
1142malloc_size_of_is_webrender_malloc_size_of!(webrender_api::GradientStop);
1143malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ImageKey);
1144malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ImageRendering);
1145malloc_size_of_is_webrender_malloc_size_of!(webrender_api::LineStyle);
1146malloc_size_of_is_webrender_malloc_size_of!(webrender_api::MixBlendMode);
1147malloc_size_of_is_webrender_malloc_size_of!(webrender_api::NormalBorder);
1148malloc_size_of_is_webrender_malloc_size_of!(webrender_api::PipelineId);
1149malloc_size_of_is_webrender_malloc_size_of!(webrender_api::ReferenceFrameKind);
1150malloc_size_of_is_webrender_malloc_size_of!(webrender_api::RepeatMode);
1151malloc_size_of_is_webrender_malloc_size_of!(webrender_api::FontVariation);
1152malloc_size_of_is_webrender_malloc_size_of!(webrender_api::SpatialId);
1153malloc_size_of_is_webrender_malloc_size_of!(webrender_api::StickyOffsetBounds);
1154malloc_size_of_is_webrender_malloc_size_of!(webrender_api::TransformStyle);
1155malloc_size_of_is_webrender_malloc_size_of!(webrender::FastTransform<webrender_api::units::LayoutPixel,webrender_api::units::LayoutPixel>);
1156
1157macro_rules! malloc_size_of_is_stylo_malloc_size_of(
1158 ($($ty:ty),+) => (
1159 $(
1160 impl MallocSizeOf for $ty {
1161 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1162 <$ty as stylo_malloc_size_of::MallocSizeOf>::size_of(self, ops)
1163 }
1164 }
1165 )+
1166 );
1167);
1168
1169impl<S> MallocSizeOf for style::author_styles::GenericAuthorStyles<S>
1170where
1171 S: style::stylesheets::StylesheetInDocument
1172 + std::cmp::PartialEq
1173 + stylo_malloc_size_of::MallocSizeOf,
1174{
1175 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1176 <style::author_styles::GenericAuthorStyles<S> as stylo_malloc_size_of::MallocSizeOf>::size_of(self, ops)
1177 }
1178}
1179
1180impl<S> MallocSizeOf for style::stylesheet_set::DocumentStylesheetSet<S>
1181where
1182 S: style::stylesheets::StylesheetInDocument
1183 + std::cmp::PartialEq
1184 + stylo_malloc_size_of::MallocSizeOf,
1185{
1186 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1187 <style::stylesheet_set::DocumentStylesheetSet<S> as stylo_malloc_size_of::MallocSizeOf>::size_of(self, ops)
1188 }
1189}
1190
1191impl<T> MallocSizeOf for style::shared_lock::Locked<T> {
1192 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
1193 0
1195 }
1197}
1198
1199impl<T: MallocSizeOf> MallocSizeOf for atomic_refcell::AtomicRefCell<T> {
1200 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1201 self.borrow().size_of(ops)
1202 }
1203}
1204
1205malloc_size_of_is_stylo_malloc_size_of!(style::animation::DocumentAnimationSet);
1206malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrIdentifier);
1207malloc_size_of_is_stylo_malloc_size_of!(style::attr::AttrValue);
1208malloc_size_of_is_stylo_malloc_size_of!(style::color::AbsoluteColor);
1209malloc_size_of_is_stylo_malloc_size_of!(style::computed_values::font_variant_caps::T);
1210malloc_size_of_is_stylo_malloc_size_of!(style::computed_values::text_decoration_style::T);
1211malloc_size_of_is_stylo_malloc_size_of!(style::dom::OpaqueNode);
1212malloc_size_of_is_stylo_malloc_size_of!(style::invalidation::element::restyle_hints::RestyleHint);
1213malloc_size_of_is_stylo_malloc_size_of!(style::logical_geometry::WritingMode);
1214malloc_size_of_is_stylo_malloc_size_of!(style::media_queries::MediaList);
1215malloc_size_of_is_stylo_malloc_size_of!(
1216 style::properties::longhands::align_items::computed_value::T
1217);
1218malloc_size_of_is_stylo_malloc_size_of!(
1219 style::properties::longhands::flex_direction::computed_value::T
1220);
1221malloc_size_of_is_stylo_malloc_size_of!(style::properties::longhands::flex_wrap::computed_value::T);
1222malloc_size_of_is_stylo_malloc_size_of!(style::properties::style_structs::Font);
1223malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::PseudoElement);
1224malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::RestyleDamage);
1225malloc_size_of_is_stylo_malloc_size_of!(style::selector_parser::Snapshot);
1226malloc_size_of_is_stylo_malloc_size_of!(style::shared_lock::SharedRwLock);
1227malloc_size_of_is_stylo_malloc_size_of!(style::stylesheets::DocumentStyleSheet);
1228malloc_size_of_is_stylo_malloc_size_of!(style::stylist::Stylist);
1229malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::BorderStyle);
1230malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::ContentDistribution);
1231malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStretch);
1232malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontStyle);
1233malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::FontWeight);
1234malloc_size_of_is_stylo_malloc_size_of!(style::values::computed::font::SingleFontFamily);
1235malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::align::AlignFlags);
1236malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::box_::Overflow);
1237malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::font::FontSynthesis);
1238malloc_size_of_is_stylo_malloc_size_of!(style::values::specified::TextDecorationLine);
1239malloc_size_of_is_stylo_malloc_size_of!(stylo_dom::ElementState);
1240malloc_size_of_is_stylo_malloc_size_of!(style::computed_values::font_optical_sizing::T);
1241
1242impl<T> MallocSizeOf for GenericLengthPercentageOrAuto<T>
1243where
1244 T: stylo_malloc_size_of::MallocSizeOf,
1245{
1246 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1247 <GenericLengthPercentageOrAuto<T> as stylo_malloc_size_of::MallocSizeOf>::size_of(self, ops)
1248 }
1249}
1250
1251impl MallocSizeOf for resvg::usvg::fontdb::Source {
1252 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1253 match self {
1254 Source::Binary(_) => 0,
1255 Source::File(path) => path.size_of(ops),
1256 Source::SharedFile(path, _) => path.size_of(ops),
1257 }
1258 }
1259}
1260
1261impl MallocSizeOf for resvg::usvg::fontdb::FaceInfo {
1262 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1263 self.id.size_of(ops) +
1264 self.source.size_of(ops) +
1265 self.families.size_of(ops) +
1266 self.post_script_name.size_of(ops) +
1267 self.style.size_of(ops) +
1268 self.weight.size_of(ops) +
1269 self.stretch.size_of(ops)
1270 }
1271}
1272
1273impl MallocSizeOf for resvg::usvg::fontdb::Database {
1274 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1275 self.faces().map(|face| face.size_of(ops)).sum()
1276 }
1277}