Growth of Vec
is rightfully handled in an uninlined #[cold]
function. Unfortunately, this makes Vec
's growth opaque to the optimizer, and the optimizer does not "know" what is the new len
and capacity
of the Vec
after reserve
.
This code should reserve capacity once:
vec.try_reserve(3)?;
vec.extend_from_slice(&[1,2,3]);
but actually tries to reserve capacity twice, because the optimizer doesn't know what (try_)reserve
does, so it keeps redundant second reserve
in extend_from_slice
.
It is fixable by adding a hint:
#[inline]
pub fn reserve(v: &mut Vec<u8>, additional: usize) {
v.try_reserve(additional).unwrap();
unsafe {
core::intrinsics::assume(additional <= v.capacity().wrapping_sub(v.len()));
}
}
but this seems to work only in user code. When I put such hints in the liballoc, they seem to have no effect at all. I've even tried #[inline(always)]
in std, but nope.
Any idea how to fix that? I presume that liballoc is special, and perhaps the hints don't survive in it?