Commits
Click on a commit to change the comparison rangefix(allocator): maintain alignment in overaligned allocations
When allocating with alignment > 8, we must round the size up to the
requested alignment, not just to 8. Otherwise, subtracting the size
from an aligned pointer results in a misaligned pointer.
This fixes hashbrown SSE2 control group panics which require 16-byte
alignment. fix(allocator): track allocations and reallocations in allocator_api2
Add tracking calls for allocate/grow/shrink in the allocator_api2 impl.
This fixes the reallocation count being 0 in allocation snapshots. perf(allocator): optimize hot path with wrapping arithmetic
Key optimizations:
1. Use usize::MAX sentinel for empty allocator's start pointer
- Eliminates null check on hot path
2. Use wrapping_sub instead of checked subtraction
- Single comparison (new_ptr >= start) replaces two branches
3. Simplify grow path with same wrapping arithmetic pattern
The hot path now has:
- 2 loads (ptr, start)
- 1 wrapping_sub
- 1 comparison (new_ptr >= start && align <= 8)
- 1 store
Previously had:
- 2 loads
- 1 null check
- 1 subtraction for available space
- 2 comparisons (available >= size, align check)
- 1 subtraction for new_ptr
- 1 store [autofix.ci] apply automated fixes6 hours ago
by autofix-ci[bot] fix(allocator): maintain alignment in grow() for non-aligned sizes
When growing allocations with sizes not aligned to ALIGN (8 bytes),
the cursor could become misaligned. For example, a Vec<u8> growing
from capacity 3 to 6 would compute additional=3, making the cursor
point to an address not divisible by 8.
Fix by computing additional as the difference between rounded sizes:
additional = round_up_to(new_size, ALIGN) - round_up_to(old_size, ALIGN)
Also handle the case where both sizes round to the same value (no
additional space needed).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> perf(allocator): increase default chunk size to match bumpalo usable space
The DEFAULT_CHUNK_SIZE was 512 bytes total, which left only 464 bytes
usable after accounting for the 48-byte footer. Bumpalo's
FIRST_ALLOCATION_GOAL is 512 bytes of *usable* space.
This 10% difference in initial usable space caused more frequent chunk
allocations, which was identified as the source of the performance
regression in build_semantic -> alloc_slow -> alloc_chunk.
Fix by setting DEFAULT_CHUNK_SIZE = 512 + FOOTER_SIZE, giving us ~512
bytes of usable space like bumpalo.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> perf(allocator): remove ineffective `likely` hint and `#[cold]` from Vec grow
- Remove `likely()` wrapper function - the `#[cold]` attribute on
`alloc_slow` already tells LLVM the slow path is unlikely
- Remove `#[cold]` from Vec's inner grow function - for interleaved
Vec growth patterns (e.g., in `tally_slot_frequencies`), this path
is actually hot, not cold. Keep `#[inline(never)]` to avoid code bloat.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>