Open
Description
An alignment is guaranteed to be a power of two. However without intrinsics it's not possible to use this guarantee when constructing a new Layout
from an old one only changing the size. For testing I used the following code:
pub fn dynamic_slow(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
let align = layout.align();
Layout::from_size_align(size, align)
}
pub fn dynamic_fast(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
let align = layout.align();
unsafe { core::intrinsics::assume(align.is_power_of_two()); }
Layout::from_size_align(size, align)
}
pub fn static_slow() -> Result<Layout, LayoutErr> {
dynamic_slow(Layout::new::<u32>(), 12)
}
pub fn static_fast() -> Result<Layout, LayoutErr> {
dynamic_fast(Layout::new::<u32>(), 12)
}
dynamic_fast
assumes, that the alignment returned from Layout
is a power of two. This results in this assembly:
example::dynamic_slow:
lea rax, [rsi - 1]
mov r8, rsi
neg r8
xor ecx, ecx
test rsi, rax
mov rdi, rsi
cmovne rdi, rcx
test rsi, rsi
cmove rdi, rsi
mov rax, rdx
cmp r8, rdx
cmovae rcx, rdi
mov rdx, rcx
ret
example::dynamic_fast:
mov rax, rdx
mov rcx, rsi
neg rcx
xor edx, edx
cmp rcx, rax
cmovae rdx, rsi
ret
example::static_slow:
mov eax, 12
mov edx, 4
ret
example::static_fast:
mov eax, 12
mov edx, 4
ret
While in the static case, this does not matter, the dynamic case don't have to check align.is_power_of_two()
.
Normally, I would create a pull request, which adds the intrinsic to Layout::align()
, but core::intrinsics::assume
is not available in const fn
s.