Closed
Description
LLVM can remove "dead" calls to malloc() (where the return value is ignored, or immediately free()-d (possibly after being compared with NULL)). However, this is basically hardcoded to the "malloc" symbol (and "free", etc.); it is not aware of jemalloc (specifically je_mallocx and je_sdallocx), which Rust uses.
LLVM is very good at removing temporary allocations, as it turns out:
extern crate libc;
extern crate test;
fn main() {
unsafe {
// totally dead (and a memory leak)
// produces no calls to libc malloc
let _ = libc::malloc(4);
// freed immediately, no allocations
libc::free(libc::malloc(4));
// allocated, used to store something temporarily, then freed
// still no allocations!
let x = libc::malloc(std::mem::size_of::<i32>() as libc::size_t);
assert!(!x.is_null());
*(x as *mut i32) = 42i32;
let y = *(x as *mut i32);
libc::free(x);
test::black_box(y);
}
}
will not call malloc or free (at -O2).
On the other hand, even the most trivial allocation using liballoc...
fn main() {
let _ = Box::new(42i32);
}
will invoke je_mallocx and je_sdallocx, even at -O3.
/cc @dotdash