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}