1use std::os::raw::c_void;
9
10#[cfg(not(feature = "allocation-tracking"))]
11#[global_allocator]
12static ALLOC: Allocator = Allocator;
13
14#[cfg(feature = "allocation-tracking")]
15#[global_allocator]
16static ALLOC: crate::tracking::AccountingAlloc<Allocator> =
17 crate::tracking::AccountingAlloc::with_allocator(Allocator);
18
19#[cfg(feature = "allocation-tracking")]
20mod tracking;
21
22pub fn dump_unmeasured() {
23 #[cfg(feature = "allocation-tracking")]
24 ALLOC.dump_unmeasured_allocations();
25}
26
27pub use crate::platform::*;
28
29type EnclosingSizeFn = unsafe extern "C" fn(*const c_void) -> usize;
30
31#[cfg(feature = "allocation-tracking")]
36unsafe extern "C" fn enclosing_size_impl(ptr: *const c_void) -> usize {
37 let (adjusted, size) = crate::ALLOC.enclosing_size(ptr);
38 if size != 0 {
39 crate::ALLOC.note_allocation(adjusted, size);
40 }
41 size
42}
43
44#[allow(non_upper_case_globals)]
45#[cfg(feature = "allocation-tracking")]
46pub static enclosing_size: Option<EnclosingSizeFn> = Some(crate::enclosing_size_impl);
47
48#[allow(non_upper_case_globals)]
49#[cfg(not(feature = "allocation-tracking"))]
50pub static enclosing_size: Option<EnclosingSizeFn> = None;
51
52#[cfg(not(any(windows, feature = "use-system-allocator", target_env = "ohos")))]
53mod platform {
54 use std::os::raw::c_void;
55
56 pub use tikv_jemallocator::Jemalloc as Allocator;
57
58 pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
64 let size = unsafe { tikv_jemallocator::usable_size(ptr) };
65 #[cfg(feature = "allocation-tracking")]
66 crate::ALLOC.note_allocation(ptr, size);
67 size
68 }
69
70 pub mod libc_compat {
72 pub use tikv_jemalloc_sys::{free, malloc, realloc};
73 }
74}
75
76#[cfg(all(
77 not(windows),
78 any(feature = "use-system-allocator", target_env = "ohos")
79))]
80mod platform {
81 pub use std::alloc::System as Allocator;
82 use std::os::raw::c_void;
83
84 pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
90 #[cfg(target_vendor = "apple")]
91 unsafe {
92 let size = libc::malloc_size(ptr);
93 #[cfg(feature = "allocation-tracking")]
94 crate::ALLOC.note_allocation(ptr, size);
95 size
96 }
97
98 #[cfg(not(target_vendor = "apple"))]
99 unsafe {
100 let size = libc::malloc_usable_size(ptr as *mut _);
101 #[cfg(feature = "allocation-tracking")]
102 crate::ALLOC.note_allocation(ptr, size);
103 size
104 }
105 }
106
107 pub mod libc_compat {
108 pub use libc::{free, malloc, realloc};
109 }
110}
111
112#[cfg(windows)]
113mod platform {
114 pub use std::alloc::System as Allocator;
115 use std::os::raw::c_void;
116
117 use windows_sys::Win32::Foundation::FALSE;
118 use windows_sys::Win32::System::Memory::{GetProcessHeap, HeapSize, HeapValidate};
119
120 pub unsafe extern "C" fn usable_size(mut ptr: *const c_void) -> usize {
126 unsafe {
127 let heap = GetProcessHeap();
128
129 if HeapValidate(heap, 0, ptr) == FALSE {
130 ptr = *(ptr as *const *const c_void).offset(-1)
131 }
132
133 let size = HeapSize(heap, 0, ptr) as usize;
134 #[cfg(feature = "allocation-tracking")]
135 crate::ALLOC.note_allocation(ptr, size);
136 size
137 }
138 }
139}