1use std::hash::{BuildHasher, Hash};
50use std::mem::size_of;
51use std::ops::Range;
52use std::ops::{Deref, DerefMut};
53use std::os::raw::c_void;
54use void::Void;
55
56type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
58
59type VoidPtrToBoolFnMut = dyn FnMut(*const c_void) -> bool;
61
62pub struct MallocSizeOfOps {
64 size_of_op: VoidPtrToSizeFn,
66
67 enclosing_size_of_op: Option<VoidPtrToSizeFn>,
72
73 have_seen_ptr_op: Option<Box<VoidPtrToBoolFnMut>>,
77}
78
79impl MallocSizeOfOps {
80 pub fn new(
81 size_of_op: VoidPtrToSizeFn,
82 enclosing_size_of_op: Option<VoidPtrToSizeFn>,
83 have_seen_ptr_op: Option<Box<VoidPtrToBoolFnMut>>,
84 ) -> Self {
85 MallocSizeOfOps {
86 size_of_op,
87 enclosing_size_of_op,
88 have_seen_ptr_op,
89 }
90 }
91
92 fn is_empty<T: ?Sized>(ptr: *const T) -> bool {
95 ptr as *const usize as usize <= 256
103 }
104
105 pub unsafe fn malloc_size_of<T: ?Sized>(&self, ptr: *const T) -> usize {
112 if MallocSizeOfOps::is_empty(ptr) {
113 0
114 } else {
115 unsafe { (self.size_of_op)(ptr as *const c_void) }
116 }
117 }
118
119 pub fn has_malloc_enclosing_size_of(&self) -> bool {
121 self.enclosing_size_of_op.is_some()
122 }
123
124 pub unsafe fn malloc_enclosing_size_of<T>(&self, ptr: *const T) -> usize {
130 assert!(!MallocSizeOfOps::is_empty(ptr));
131 unsafe { (self.enclosing_size_of_op.unwrap())(ptr as *const c_void) }
132 }
133
134 pub fn have_seen_ptr<T>(&mut self, ptr: *const T) -> bool {
136 let have_seen_ptr_op = self
137 .have_seen_ptr_op
138 .as_mut()
139 .expect("missing have_seen_ptr_op");
140 have_seen_ptr_op(ptr as *const c_void)
141 }
142}
143
144pub trait MallocSizeOf {
147 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
150}
151
152pub trait MallocShallowSizeOf {
154 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
159}
160
161pub trait MallocUnconditionalSizeOf {
165 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
168}
169
170pub trait MallocUnconditionalShallowSizeOf {
172 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
174}
175
176pub trait MallocConditionalSizeOf {
180 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
184}
185
186pub trait MallocConditionalShallowSizeOf {
188 fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize;
190}
191
192impl MallocSizeOf for String {
193 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
194 unsafe { ops.malloc_size_of(self.as_ptr()) }
195 }
196}
197
198impl<T: ?Sized> MallocSizeOf for &T {
199 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
200 0
202 }
203}
204
205impl<T: ?Sized> MallocShallowSizeOf for Box<T> {
206 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
207 unsafe { ops.malloc_size_of(&**self) }
208 }
209}
210
211impl<T: MallocSizeOf + ?Sized> MallocSizeOf for Box<T> {
212 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
213 self.shallow_size_of(ops) + (**self).size_of(ops)
214 }
215}
216
217impl MallocSizeOf for () {
218 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
219 0
220 }
221}
222
223impl<T1, T2> MallocSizeOf for (T1, T2)
224where
225 T1: MallocSizeOf,
226 T2: MallocSizeOf,
227{
228 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
229 self.0.size_of(ops) + self.1.size_of(ops)
230 }
231}
232
233impl<T1, T2, T3> MallocSizeOf for (T1, T2, T3)
234where
235 T1: MallocSizeOf,
236 T2: MallocSizeOf,
237 T3: MallocSizeOf,
238{
239 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
240 self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops)
241 }
242}
243
244impl<T1, T2, T3, T4> MallocSizeOf for (T1, T2, T3, T4)
245where
246 T1: MallocSizeOf,
247 T2: MallocSizeOf,
248 T3: MallocSizeOf,
249 T4: MallocSizeOf,
250{
251 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
252 self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) + self.3.size_of(ops)
253 }
254}
255
256impl<T: MallocSizeOf> MallocSizeOf for Option<T> {
257 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
258 if let Some(val) = self.as_ref() {
259 val.size_of(ops)
260 } else {
261 0
262 }
263 }
264}
265
266impl<T: MallocSizeOf, E: MallocSizeOf> MallocSizeOf for Result<T, E> {
267 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
268 match *self {
269 Ok(ref x) => x.size_of(ops),
270 Err(ref e) => e.size_of(ops),
271 }
272 }
273}
274
275impl<T: MallocSizeOf + Copy> MallocSizeOf for std::cell::Cell<T> {
276 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
277 self.get().size_of(ops)
278 }
279}
280
281impl<T: MallocSizeOf> MallocSizeOf for std::cell::RefCell<T> {
282 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
283 self.borrow().size_of(ops)
284 }
285}
286
287impl<T: MallocSizeOf> MallocSizeOf for std::sync::OnceLock<T> {
288 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
289 self.get()
290 .map(|value| value.size_of(ops))
291 .unwrap_or_default()
292 }
293}
294
295impl<'a, B: ?Sized + ToOwned> MallocSizeOf for std::borrow::Cow<'a, B>
296where
297 B::Owned: MallocSizeOf,
298{
299 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
300 match *self {
301 std::borrow::Cow::Borrowed(_) => 0,
302 std::borrow::Cow::Owned(ref b) => b.size_of(ops),
303 }
304 }
305}
306
307impl<T: MallocSizeOf> MallocSizeOf for [T] {
308 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
309 let mut n = 0;
310 for elem in self.iter() {
311 n += elem.size_of(ops);
312 }
313 n
314 }
315}
316
317impl<T> MallocShallowSizeOf for Vec<T> {
318 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
319 unsafe { ops.malloc_size_of(self.as_ptr()) }
320 }
321}
322
323impl<T: MallocSizeOf> MallocSizeOf for Vec<T> {
324 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
325 let mut n = self.shallow_size_of(ops);
326 for elem in self.iter() {
327 n += elem.size_of(ops);
328 }
329 n
330 }
331}
332
333impl<T> MallocShallowSizeOf for std::collections::VecDeque<T> {
334 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
335 if ops.has_malloc_enclosing_size_of() {
336 if let Some(front) = self.front() {
337 unsafe { ops.malloc_enclosing_size_of(front) }
339 } else {
340 0
342 }
343 } else {
344 self.capacity() * size_of::<T>()
346 }
347 }
348}
349
350impl<T: MallocSizeOf> MallocSizeOf for std::collections::VecDeque<T> {
351 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
352 let mut n = self.shallow_size_of(ops);
353 for elem in self.iter() {
354 n += elem.size_of(ops);
355 }
356 n
357 }
358}
359
360impl<A: smallvec::Array> MallocShallowSizeOf for smallvec::SmallVec<A> {
361 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
362 if self.spilled() {
363 unsafe { ops.malloc_size_of(self.as_ptr()) }
364 } else {
365 0
366 }
367 }
368}
369
370impl<A> MallocSizeOf for smallvec::SmallVec<A>
371where
372 A: smallvec::Array,
373 A::Item: MallocSizeOf,
374{
375 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
376 let mut n = self.shallow_size_of(ops);
377 for elem in self.iter() {
378 n += elem.size_of(ops);
379 }
380 n
381 }
382}
383
384impl<T> MallocShallowSizeOf for thin_vec::ThinVec<T> {
385 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
386 if self.capacity() == 0 {
387 return 0;
389 }
390
391 assert_eq!(
392 std::mem::size_of::<Self>(),
393 std::mem::size_of::<*const ()>()
394 );
395 unsafe { ops.malloc_size_of(*(self as *const Self as *const *const ())) }
396 }
397}
398
399impl<T: MallocSizeOf> MallocSizeOf for thin_vec::ThinVec<T> {
400 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
401 let mut n = self.shallow_size_of(ops);
402 for elem in self.iter() {
403 n += elem.size_of(ops);
404 }
405 n
406 }
407}
408
409macro_rules! malloc_size_of_hash_set {
410 ($ty:ty) => {
411 impl<T, S> MallocShallowSizeOf for $ty
412 where
413 T: Eq + Hash,
414 S: BuildHasher,
415 {
416 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
417 if ops.has_malloc_enclosing_size_of() {
418 self.iter()
423 .next()
424 .map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) })
425 } else {
426 self.capacity() * (size_of::<T>() + size_of::<usize>())
428 }
429 }
430 }
431
432 impl<T, S> MallocSizeOf for $ty
433 where
434 T: Eq + Hash + MallocSizeOf,
435 S: BuildHasher,
436 {
437 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
438 let mut n = self.shallow_size_of(ops);
439 for t in self.iter() {
440 n += t.size_of(ops);
441 }
442 n
443 }
444 }
445 };
446}
447
448malloc_size_of_hash_set!(std::collections::HashSet<T, S>);
449malloc_size_of_hash_set!(hashbrown::HashSet<T, S>);
450
451macro_rules! malloc_size_of_hash_map {
452 ($ty:ty) => {
453 impl<K, V, S> MallocShallowSizeOf for $ty
454 where
455 K: Eq + Hash,
456 S: BuildHasher,
457 {
458 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
459 if ops.has_malloc_enclosing_size_of() {
461 self.values()
462 .next()
463 .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
464 } else {
465 self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
466 }
467 }
468 }
469
470 impl<K, V, S> MallocSizeOf for $ty
471 where
472 K: Eq + Hash + MallocSizeOf,
473 V: MallocSizeOf,
474 S: BuildHasher,
475 {
476 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
477 let mut n = self.shallow_size_of(ops);
478 for (k, v) in self.iter() {
479 n += k.size_of(ops);
480 n += v.size_of(ops);
481 }
482 n
483 }
484 }
485 };
486}
487
488malloc_size_of_hash_map!(std::collections::HashMap<K, V, S>);
489malloc_size_of_hash_map!(hashbrown::HashMap<K, V, S>);
490
491impl<K, V> MallocShallowSizeOf for std::collections::BTreeMap<K, V>
492where
493 K: Eq + Hash,
494{
495 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
496 if ops.has_malloc_enclosing_size_of() {
497 self.values()
498 .next()
499 .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) })
500 } else {
501 self.len() * (size_of::<V>() + size_of::<K>() + size_of::<usize>())
502 }
503 }
504}
505
506impl<K, V> MallocSizeOf for std::collections::BTreeMap<K, V>
507where
508 K: Eq + Hash + MallocSizeOf,
509 V: MallocSizeOf,
510{
511 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
512 let mut n = self.shallow_size_of(ops);
513 for (k, v) in self.iter() {
514 n += k.size_of(ops);
515 n += v.size_of(ops);
516 }
517 n
518 }
519}
520
521impl<T> MallocSizeOf for std::marker::PhantomData<T> {
523 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
524 0
525 }
526}
527
528impl<T> MallocUnconditionalShallowSizeOf for servo_arc::Arc<T> {
536 fn unconditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
537 unsafe { ops.malloc_size_of(self.heap_ptr()) }
538 }
539}
540
541impl<T: MallocSizeOf> MallocUnconditionalSizeOf for servo_arc::Arc<T> {
542 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
543 self.unconditional_shallow_size_of(ops) + (**self).size_of(ops)
544 }
545}
546
547impl<T> MallocConditionalShallowSizeOf for servo_arc::Arc<T> {
548 fn conditional_shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
549 if ops.have_seen_ptr(self.heap_ptr()) {
550 0
551 } else {
552 self.unconditional_shallow_size_of(ops)
553 }
554 }
555}
556
557impl<T: MallocSizeOf> MallocConditionalSizeOf for servo_arc::Arc<T> {
558 fn conditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
559 if ops.have_seen_ptr(self.heap_ptr()) {
560 0
561 } else {
562 self.unconditional_size_of(ops)
563 }
564 }
565}
566
567impl<T: MallocSizeOf> MallocSizeOf for std::sync::Mutex<T> {
574 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
575 (*self.lock().unwrap()).size_of(ops)
576 }
577}
578
579impl MallocSizeOf for smallbitvec::SmallBitVec {
580 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
581 if let Some(ptr) = self.heap_ptr() {
582 unsafe { ops.malloc_size_of(ptr) }
583 } else {
584 0
585 }
586 }
587}
588
589impl<T: MallocSizeOf, Unit> MallocSizeOf for euclid::Length<T, Unit> {
590 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
591 self.0.size_of(ops)
592 }
593}
594
595impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Scale<T, Src, Dst> {
596 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
597 self.0.size_of(ops)
598 }
599}
600
601impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Point2D<T, U> {
602 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
603 self.x.size_of(ops) + self.y.size_of(ops)
604 }
605}
606
607impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Rect<T, U> {
608 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
609 self.origin.size_of(ops) + self.size.size_of(ops)
610 }
611}
612
613impl<T: MallocSizeOf, U> MallocSizeOf for euclid::SideOffsets2D<T, U> {
614 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
615 self.top.size_of(ops)
616 + self.right.size_of(ops)
617 + self.bottom.size_of(ops)
618 + self.left.size_of(ops)
619 }
620}
621
622impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Size2D<T, U> {
623 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
624 self.width.size_of(ops) + self.height.size_of(ops)
625 }
626}
627
628impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform2D<T, Src, Dst> {
629 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
630 self.m11.size_of(ops)
631 + self.m12.size_of(ops)
632 + self.m21.size_of(ops)
633 + self.m22.size_of(ops)
634 + self.m31.size_of(ops)
635 + self.m32.size_of(ops)
636 }
637}
638
639impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::Transform3D<T, Src, Dst> {
640 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
641 self.m11.size_of(ops)
642 + self.m12.size_of(ops)
643 + self.m13.size_of(ops)
644 + self.m14.size_of(ops)
645 + self.m21.size_of(ops)
646 + self.m22.size_of(ops)
647 + self.m23.size_of(ops)
648 + self.m24.size_of(ops)
649 + self.m31.size_of(ops)
650 + self.m32.size_of(ops)
651 + self.m33.size_of(ops)
652 + self.m34.size_of(ops)
653 + self.m41.size_of(ops)
654 + self.m42.size_of(ops)
655 + self.m43.size_of(ops)
656 + self.m44.size_of(ops)
657 }
658}
659
660impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Vector2D<T, U> {
661 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
662 self.x.size_of(ops) + self.y.size_of(ops)
663 }
664}
665
666impl MallocSizeOf for selectors::parser::AncestorHashes {
667 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
668 let selectors::parser::AncestorHashes { ref packed_hashes } = *self;
669 packed_hashes.size_of(ops)
670 }
671}
672
673impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
674 for selectors::parser::Selector<Impl>
675where
676 Impl::NonTSPseudoClass: MallocSizeOf,
677 Impl::PseudoElement: MallocSizeOf,
678{
679 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
680 let mut n = 0;
681
682 n += unsafe { ops.malloc_size_of(self.thin_arc_heap_ptr()) };
686 for component in self.iter_raw_match_order() {
687 n += component.size_of(ops);
688 }
689
690 n
691 }
692}
693
694impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
695 for selectors::parser::SelectorList<Impl>
696where
697 Impl::NonTSPseudoClass: MallocSizeOf,
698 Impl::PseudoElement: MallocSizeOf,
699{
700 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
701 let mut n = 0;
702
703 n += unsafe { ops.malloc_size_of(self.thin_arc_heap_ptr()) };
706 if self.len() > 1 {
707 for selector in self.slice().iter() {
708 n += selector.size_of(ops);
709 }
710 }
711 n
712 }
713}
714
715impl<Impl: selectors::parser::SelectorImpl> MallocUnconditionalSizeOf
716 for selectors::parser::Component<Impl>
717where
718 Impl::NonTSPseudoClass: MallocSizeOf,
719 Impl::PseudoElement: MallocSizeOf,
720{
721 fn unconditional_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
722 use selectors::parser::Component;
723
724 match self {
725 Component::AttributeOther(attr_selector) => attr_selector.size_of(ops),
726 Component::Negation(components) => components.unconditional_size_of(ops),
727 Component::NonTSPseudoClass(pseudo) => (*pseudo).size_of(ops),
728 Component::Slotted(selector) | Component::Host(Some(selector)) => {
729 selector.unconditional_size_of(ops)
730 },
731 Component::Is(list) | Component::Where(list) => list.unconditional_size_of(ops),
732 Component::Has(relative_selectors) => relative_selectors.size_of(ops),
733 Component::NthOf(nth_of_data) => nth_of_data.size_of(ops),
734 Component::PseudoElement(pseudo) => (*pseudo).size_of(ops),
735 Component::Combinator(..)
736 | Component::ExplicitAnyNamespace
737 | Component::ExplicitNoNamespace
738 | Component::DefaultNamespace(..)
739 | Component::Namespace(..)
740 | Component::ExplicitUniversalType
741 | Component::LocalName(..)
742 | Component::ID(..)
743 | Component::Part(..)
744 | Component::Class(..)
745 | Component::AttributeInNoNamespaceExists { .. }
746 | Component::AttributeInNoNamespace { .. }
747 | Component::Root
748 | Component::Empty
749 | Component::Scope
750 | Component::ImplicitScope
751 | Component::ParentSelector
752 | Component::Nth(..)
753 | Component::Host(None)
754 | Component::RelativeSelectorAnchor
755 | Component::Invalid(..) => 0,
756 }
757 }
758}
759
760impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf
761 for selectors::attr::AttrSelectorWithOptionalNamespace<Impl>
762{
763 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
764 0
765 }
766}
767
768impl MallocSizeOf for selectors::parser::AnPlusB {
769 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
770 0
771 }
772}
773
774impl MallocSizeOf for Void {
775 #[inline]
776 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
777 void::unreachable(*self)
778 }
779}
780
781#[cfg(feature = "servo")]
782impl<Static: string_cache::StaticAtomSet> MallocSizeOf for string_cache::Atom<Static> {
783 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
784 0
785 }
786}
787
788#[macro_export]
790macro_rules! malloc_size_of_is_0(
791 ($($ty:ty),+) => (
792 $(
793 impl $crate::MallocSizeOf for $ty {
794 #[inline(always)]
795 fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
796 0
797 }
798 }
799 )+
800 );
801 ($($ty:ident<$($gen:ident),+>),+) => (
802 $(
803 impl<$($gen: $crate::MallocSizeOf),+> $crate::MallocSizeOf for $ty<$($gen),+> {
804 #[inline(always)]
805 fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
806 0
807 }
808 }
809 )+
810 );
811);
812
813malloc_size_of_is_0!(bool, char, str);
814malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize);
815malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize);
816malloc_size_of_is_0!(f32, f64);
817
818malloc_size_of_is_0!(std::sync::atomic::AtomicBool);
819malloc_size_of_is_0!(std::sync::atomic::AtomicIsize);
820malloc_size_of_is_0!(std::sync::atomic::AtomicU32);
821malloc_size_of_is_0!(std::sync::atomic::AtomicUsize);
822malloc_size_of_is_0!(std::num::NonZeroUsize);
823malloc_size_of_is_0!(std::num::NonZeroU64);
824
825malloc_size_of_is_0!(Range<u8>, Range<u16>, Range<u32>, Range<u64>, Range<usize>);
826malloc_size_of_is_0!(Range<i8>, Range<i16>, Range<i32>, Range<i64>, Range<isize>);
827malloc_size_of_is_0!(Range<f32>, Range<f64>);
828
829malloc_size_of_is_0!(app_units::Au);
830
831malloc_size_of_is_0!(
832 cssparser::TokenSerializationType,
833 cssparser::SourceLocation,
834 cssparser::SourcePosition,
835 cssparser::UnicodeRange
836);
837
838malloc_size_of_is_0!(selectors::OpaqueElement);
839
840#[derive(Clone)]
843pub struct Measurable<T: MallocSizeOf>(pub T);
844
845impl<T: MallocSizeOf> Deref for Measurable<T> {
846 type Target = T;
847
848 fn deref(&self) -> &T {
849 &self.0
850 }
851}
852
853impl<T: MallocSizeOf> DerefMut for Measurable<T> {
854 fn deref_mut(&mut self) -> &mut T {
855 &mut self.0
856 }
857}
858
859impl<T: MallocSizeOf> MallocSizeOf for parking_lot::RwLock<T> {
860 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
861 self.read().size_of(ops)
862 }
863}