parity_util_mem/
allocators.rs1#[cfg(feature = "std")]
33use crate::malloc_size::MallocUnconditionalSizeOf;
34use crate::malloc_size::{MallocSizeOf, MallocSizeOfOps, VoidPtrToSizeFn};
35#[cfg(not(feature = "std"))]
36use core::ffi::c_void;
37#[cfg(feature = "std")]
38use std::os::raw::c_void;
39
40mod usable_size {
41
42 use super::*;
43
44 cfg_if::cfg_if! {
45
46 if #[cfg(any(
47 target_arch = "wasm32",
48 feature = "estimate-heapsize",
49 feature = "dlmalloc-global",
50 ))] {
51
52 pub unsafe extern "C" fn malloc_usable_size(_ptr: *const c_void) -> usize {
58 unreachable!("estimate heapsize only")
59 }
60
61 } else if #[cfg(target_os = "windows")] {
62
63 use winapi::um::heapapi::{GetProcessHeap, HeapSize, HeapValidate};
64 use winapi::ctypes::c_void as winapi_c_void;
65
66 pub unsafe extern "C" fn malloc_usable_size(mut ptr: *const c_void) -> usize {
69
70 let heap = GetProcessHeap();
71
72 if HeapValidate(heap, 0, ptr as *const winapi_c_void) == 0 {
73 ptr = *(ptr as *const *const c_void).offset(-1);
74 }
75
76 HeapSize(heap, 0, ptr as *const winapi_c_void) as usize
77 }
78
79 } else if #[cfg(feature = "jemalloc-global")] {
80
81 pub unsafe extern "C" fn malloc_usable_size(ptr: *const c_void) -> usize {
83 tikv_jemallocator::usable_size(ptr)
84 }
85
86 } else if #[cfg(feature = "mimalloc-global")] {
87
88 pub unsafe extern "C" fn malloc_usable_size(ptr: *const c_void) -> usize {
90 libmimalloc_sys::mi_usable_size(ptr as *mut _)
93 }
94
95 } else if #[cfg(any(
96 target_os = "linux",
97 target_os = "android",
98 target_os = "freebsd",
99 ))] {
100 extern "C" {
102 pub fn malloc_usable_size(ptr: *const c_void) -> usize;
103 }
104
105 } else {
106 pub unsafe extern "C" fn malloc_usable_size(_ptr: *const c_void) -> usize {
108 unreachable!("estimate heapsize or feature allocator needed")
109 }
110
111 }
112
113 }
114
115 #[inline]
117 pub fn new_enclosing_size_fn() -> Option<VoidPtrToSizeFn> {
118 None
119 }
120}
121
122pub fn new_malloc_size_ops() -> MallocSizeOfOps {
124 MallocSizeOfOps::new(usable_size::malloc_usable_size, usable_size::new_enclosing_size_fn(), None)
125}
126
127pub trait MallocSizeOfExt: MallocSizeOf {
132 fn malloc_size_of(&self) -> usize {
135 let mut ops = new_malloc_size_ops();
136 <Self as MallocSizeOf>::size_of(self, &mut ops)
137 }
138}
139
140impl<T: MallocSizeOf> MallocSizeOfExt for T {}
141
142#[cfg(feature = "std")]
143impl<T: MallocSizeOf> MallocSizeOf for std::sync::Arc<T> {
144 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
145 self.unconditional_size_of(ops)
146 }
147}