Skip to content

Commit

Permalink
feat: don't align the bump pointer for allocations which's size happe…
Browse files Browse the repository at this point in the history
…ns to be a multiple of `MIN_ALIGN` (#15)
  • Loading branch information
bluurryy committed Apr 25, 2024
1 parent c2c9082 commit 4b51991
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 7 deletions.
4 changes: 4 additions & 0 deletions crates/inspect-asm/inspect-asm.nu
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ def --wrapped main [
}
}

for dir in [up, down, down_big] {
$names ++= $"alloc_overaligned_but_size_matches::($dir)"
}

# for prefix in ["", try_] {
# $names ++= $"alloc_with_drop::($prefix)up"
# $names ++= $"alloc_with_drop::($prefix)up_a"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
inspect_asm::alloc_overaligned_but_size_matches::down:
push rbx
mov rcx, qword ptr [rdi]
mov rax, qword ptr [rcx]
add rax, -4
cmp rax, qword ptr [rcx + 8]
jb .LBB_2
mov qword ptr [rcx], rax
mov dword ptr [rax], esi
pop rbx
ret
.LBB_2:
mov ebx, esi
call bump_scope::bump_scope::BumpScope<A,_,_,_>::do_alloc_sized_in_another_chunk
mov esi, ebx
mov dword ptr [rax], esi
pop rbx
ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
inspect_asm::alloc_overaligned_but_size_matches::down_big:
push rbx
mov rcx, qword ptr [rdi]
mov rax, qword ptr [rcx]
mov rdx, rax
sub rdx, qword ptr [rcx + 8]
cmp rdx, 40
jb .LBB_2
add rax, -40
mov qword ptr [rcx], rax
.LBB_3:
mov rcx, qword ptr [rsi + 32]
mov qword ptr [rax + 32], rcx
movups xmm0, xmmword ptr [rsi]
movups xmm1, xmmword ptr [rsi + 16]
movups xmmword ptr [rax + 16], xmm1
movups xmmword ptr [rax], xmm0
pop rbx
ret
.LBB_2:
mov rbx, rsi
call bump_scope::bump_scope::BumpScope<A,_,_,_>::do_alloc_sized_in_another_chunk
mov rsi, rbx
jmp .LBB_3
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
inspect_asm::alloc_overaligned_but_size_matches::up:
push rbx
mov rcx, qword ptr [rdi]
mov rax, qword ptr [rcx]
mov rdx, qword ptr [rcx + 8]
sub rdx, rax
cmp rdx, 4
jb .LBB_2
lea rdx, [rax + 4]
mov qword ptr [rcx], rdx
mov dword ptr [rax], esi
pop rbx
ret
.LBB_2:
mov ebx, esi
call bump_scope::bump_scope::BumpScope<A,_,_,_>::do_alloc_sized_in_another_chunk
mov esi, ebx
mov dword ptr [rax], esi
pop rbx
ret
16 changes: 16 additions & 0 deletions crates/inspect-asm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ cases! {
mod alloc_u32_slice_clone fn(bump, value: &[u32]) -> &'a mut [u32] { bump.alloc_slice_clone(value) } in { bump.try_alloc_slice_clone(value) }
}

pub mod alloc_overaligned_but_size_matches {
use super::*;

pub fn up(bump: &Bump<4, true>, value: [u8; 4]) -> &[u8; 4] {
bump.alloc(value).into_ref()
}

pub fn down(bump: &Bump<4, false>, value: [u8; 4]) -> &[u8; 4] {
bump.alloc(value).into_ref()
}

pub fn down_big(bump: &Bump<4, false>, value: [u8; 40]) -> &[u8; 40] {
bump.alloc(value).into_ref()
}
}

#[derive(Clone)]
#[allow(dead_code)]
pub struct foo(u64);
Expand Down
22 changes: 15 additions & 7 deletions src/chunk_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ impl<const UP: bool, A> RawChunk<UP, A> {
start = aligned_down + layout.align();
};

if IS_CONST_ALIGN && L::IS_ARRAY_LAYOUT && layout.align() >= MIN_ALIGN {
if (IS_CONST_ALIGN && L::IS_ARRAY_LAYOUT && layout.align() >= MIN_ALIGN)
|| (IS_CONST_SIZE && (layout.size() % MIN_ALIGN == 0))
{
// we are already aligned to `MIN_ALIGN`
} else {
// up aligning an address `<= range.end` with an alignment `<= CHUNK_ALIGN_MIN` (which `MIN_ALIGN` is)
Expand All @@ -219,9 +221,13 @@ impl<const UP: bool, A> RawChunk<UP, A> {
// thus its address can't be smaller than it.
end -= layout.size();

if IS_CONST_ALIGN && L::IS_ARRAY_LAYOUT && layout.align() == MIN_ALIGN {
// we are already aligned to `MIN_ALIGN`
} else {
let needs_align_for_min_align = (!IS_CONST_ALIGN || !L::IS_ARRAY_LAYOUT || layout.align() < MIN_ALIGN)
&& (!IS_CONST_SIZE || (layout.size() % MIN_ALIGN != 0));
let needs_align_for_layout = !IS_CONST_ALIGN || !L::IS_ARRAY_LAYOUT || layout.align() > MIN_ALIGN;

if needs_align_for_min_align || needs_align_for_layout {
// At this point layout's align is const, because we assume `IS_CONST_SIZE` implies `IS_CONST_ALIGN`.
// That means `max` is evaluated at compile time, so we don't bother having different cases for either alignment.
end = down_align_usize(end, layout.align().max(MIN_ALIGN));
}

Expand All @@ -239,9 +245,11 @@ impl<const UP: bool, A> RawChunk<UP, A> {
// doesn't overflow because of the check above
end -= layout.size();

if IS_CONST_ALIGN && L::IS_ARRAY_LAYOUT && layout.align() == MIN_ALIGN {
// we are already aligned to `MIN_ALIGN`
} else {
let needs_align_for_min_align = (!IS_CONST_ALIGN || !L::IS_ARRAY_LAYOUT || layout.align() < MIN_ALIGN)
&& (!IS_CONST_SIZE || (layout.size() % MIN_ALIGN != 0));
let needs_align_for_layout = !IS_CONST_ALIGN || !L::IS_ARRAY_LAYOUT || layout.align() > MIN_ALIGN;

if needs_align_for_min_align || needs_align_for_layout {
// down aligning an address `>= range.start` with an alignment `<= CHUNK_ALIGN_MIN` (which `layout.align()` is)
// can not exceed `range.start`, and thus also can't overflow
end = down_align_usize(end, layout.align().max(MIN_ALIGN));
Expand Down

0 comments on commit 4b51991

Please sign in to comment.