mmtk/util/malloc/mod.rs
1//! This module exposes a set of malloc API. They are currently implemented with
2//! the library malloc. This may change in the future, and will be replaced
3//! with a native MMTk implementation.
4
5//! We have two versions for each function:
6//! * a normal version: it has the signature that is compatible with the standard malloc library.
7//! * a counted version: the allocated/freed bytes are calculated into MMTk's heap. So extra arguments
8//! are needed to maintain allocated bytes properly. The API is inspired by Julia's counted malloc.
9//! The counted version is only available with the feature `malloc_counted_size`.
10
11/// Malloc provided by libraries
12pub(crate) mod library;
13/// Using malloc as mark sweep free-list allocator.
14pub(crate) mod malloc_ms_util;
15
16use crate::util::Address;
17#[cfg(feature = "malloc_counted_size")]
18use crate::vm::VMBinding;
19#[cfg(feature = "malloc_counted_size")]
20use crate::MMTK;
21
22/// Manually allocate memory. Similar to libc's malloc.
23pub fn malloc(size: usize) -> Address {
24 Address::from_mut_ptr(unsafe { self::library::malloc(size) })
25}
26
27/// Manually allocate memory. Similar to libc's malloc.
28/// This also counts the allocated memory into the heap size of the given MMTk instance.
29#[cfg(feature = "malloc_counted_size")]
30pub fn counted_malloc<VM: VMBinding>(mmtk: &MMTK<VM>, size: usize) -> Address {
31 let res = malloc(size);
32 if !res.is_zero() {
33 mmtk.state.increase_malloc_bytes_by(size);
34 }
35 res
36}
37
38/// Manually allocate memory and initialize the bytes in the allocated memory to zero. Similar to libc's calloc.
39pub fn calloc(num: usize, size: usize) -> Address {
40 Address::from_mut_ptr(unsafe { self::library::calloc(num, size) })
41}
42
43/// Manually allocate memory and initialize the bytes in the allocated memory to zero. Similar to libc's calloc.
44/// This also counts the allocated memory into the heap size of the given MMTk instance.
45#[cfg(feature = "malloc_counted_size")]
46pub fn counted_calloc<VM: VMBinding>(mmtk: &MMTK<VM>, num: usize, size: usize) -> Address {
47 let res = calloc(num, size);
48 if !res.is_zero() {
49 mmtk.state.increase_malloc_bytes_by(num * size);
50 }
51 res
52}
53
54/// Reallocate the given area of memory. Similar to libc's realloc.
55pub fn realloc(addr: Address, size: usize) -> Address {
56 Address::from_mut_ptr(unsafe { self::library::realloc(addr.to_mut_ptr(), size) })
57}
58
59/// Reallocate the given area of memory. Similar to libc's realloc.
60/// This also adjusts the allocated memory size based on the original allocation and the new allocation, and counts
61/// that into the heap size for the given MMTk instance.
62#[cfg(feature = "malloc_counted_size")]
63pub fn realloc_with_old_size<VM: VMBinding>(
64 mmtk: &MMTK<VM>,
65 addr: Address,
66 size: usize,
67 old_size: usize,
68) -> Address {
69 let res = realloc(addr, size);
70
71 if !addr.is_zero() {
72 mmtk.state.decrease_malloc_bytes_by(old_size);
73 }
74 if size != 0 && !res.is_zero() {
75 mmtk.state.increase_malloc_bytes_by(size);
76 }
77
78 res
79}
80
81/// Manually free the memory that is returned from other manual allocation functions in this module.
82pub fn free(addr: Address) {
83 unsafe { self::library::free(addr.to_mut_ptr()) }
84}
85
86/// Manually free the memory that is returned from other manual allocation functions in this module.
87/// This also reduces the allocated memory size.
88#[cfg(feature = "malloc_counted_size")]
89pub fn free_with_size<VM: VMBinding>(mmtk: &MMTK<VM>, addr: Address, old_size: usize) {
90 free(addr);
91 if !addr.is_zero() {
92 mmtk.state.decrease_malloc_bytes_by(old_size);
93 }
94}