mmtk/util/malloc/
malloc_ms_util.rs1use crate::util::constants::BYTES_IN_ADDRESS;
2use crate::util::malloc::library::*;
3use crate::util::Address;
4use crate::vm::VMBinding;
5
6pub fn align_alloc(size: usize, align: usize) -> Address {
8 let mut ptr = std::ptr::null_mut::<libc::c_void>();
9 let ptr_ptr = std::ptr::addr_of_mut!(ptr);
10 let result = unsafe { posix_memalign(ptr_ptr, align, size) };
11 if result != 0 {
12 return Address::ZERO;
13 }
14 let address = Address::from_mut_ptr(ptr);
15 crate::util::memory::zero(address, size);
16 address
17}
18
19pub fn align_offset_alloc<VM: VMBinding>(size: usize, align: usize, offset: usize) -> Address {
23 let actual_size = size + align + BYTES_IN_ADDRESS;
25 let raw = unsafe { calloc(1, actual_size) };
26 let address = Address::from_mut_ptr(raw);
27 if address.is_zero() {
28 return address;
29 }
30 let mod_offset = offset % align;
31 let mut result =
32 crate::util::alloc::allocator::align_allocation_no_fill::<VM>(address, align, mod_offset);
33 if result - BYTES_IN_ADDRESS < address {
34 result += align;
35 }
36 let malloc_res_ptr: *mut usize = (result - BYTES_IN_ADDRESS).to_mut_ptr();
37 unsafe { malloc_res_ptr.write_unaligned(address.as_usize()) };
38 result
39}
40
41pub fn offset_malloc_usable_size(address: Address) -> usize {
43 let malloc_res_ptr: *mut usize = (address - BYTES_IN_ADDRESS).to_mut_ptr();
44 let malloc_res = unsafe { malloc_res_ptr.read_unaligned() } as *mut libc::c_void;
45 unsafe { malloc_usable_size(malloc_res) }
46}
47
48pub fn offset_free(address: Address) {
50 let malloc_res_ptr: *mut usize = (address - BYTES_IN_ADDRESS).to_mut_ptr();
51 let malloc_res = unsafe { malloc_res_ptr.read_unaligned() } as *mut libc::c_void;
52 unsafe { free(malloc_res) };
53}
54
55pub use crate::util::malloc::library::free;
56
57pub fn get_malloc_usable_size(address: Address, is_offset_malloc: bool) -> usize {
60 if is_offset_malloc {
61 offset_malloc_usable_size(address)
62 } else {
63 unsafe { malloc_usable_size(address.to_mut_ptr()) }
64 }
65}
66
67pub fn alloc<VM: VMBinding>(size: usize, align: usize, offset: usize) -> (Address, bool) {
70 let address: Address;
71 let mut is_offset_malloc = false;
72 if align <= 16 && offset == 0 {
75 let raw = unsafe { calloc(1, size) };
76 address = Address::from_mut_ptr(raw);
77 debug_assert!(address.is_aligned_to(align));
78 } else if align > 16 && offset == 0 {
79 address = align_alloc(size, align);
80 debug_assert!(
81 address.is_aligned_to(align),
82 "Address: {:x} is not aligned to the given alignment: {}",
83 address,
84 align
85 );
86 } else {
87 address = align_offset_alloc::<VM>(size, align, offset);
88 is_offset_malloc = true;
89 debug_assert!(
90 (address + offset).is_aligned_to(align),
91 "Address: {:x} is not aligned to the given alignment: {} at offset: {}",
92 address,
93 align,
94 offset
95 );
96 }
97 (address, is_offset_malloc)
98}