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