Skip to content

Commit

Permalink
Auto merge of rust-lang#118228 - Mark-Simulacrum:alloc-opt, r=scottmcm
Browse files Browse the repository at this point in the history
Indicate that multiplication in Layout::array cannot overflow

Since rust-lang#113113, we have added a check that skips calling into the allocator at all if `capacity == 0`. The global, default allocator will not actually try to allocate though; it returns a dangling pointer explicitly. However, these two checks are not merged/deduplicated by LLVM and so we're comparing to zero twice whenever vectors are allocated/grown. Probably cheap, but also potentially expensive in code size and seems like an unfortunate miss.

This removes that extra check by telling LLVM that the multiplication as part of Layout::array can't overflow, turning the original non-zero value into a zero value afterwards. In my checks locally this successfully drops the duplicate comparisons.

See https://rust.godbolt.org/z/b6nPP9dcK for a code example.

```rust
pub fn foo(elements: usize) -> Vec<u32> {
    Vec::with_capacity(elements)
}
```

r? `@scottmcm` since you touched this in a32305a - curious if you have thoughts on doing this / can confirm my model of this being correct.
  • Loading branch information
bors committed Nov 24, 2023
2 parents f74f700 + b81e788 commit b06258c
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,11 @@ impl Layout {
return Err(LayoutError);
}

let array_size = element_size * n;
// SAFETY: We just checked that we won't overflow `usize` when we multiply.
// This is a useless hint inside this function, but after inlining this helps
// deduplicate checks for whether the overall capacity is zero (e.g., in RawVec's
// allocation path) before/after this multiplication.
let array_size = unsafe { element_size.unchecked_mul(n) };

// SAFETY: We just checked above that the `array_size` will not
// exceed `isize::MAX` even when rounded up to the alignment.
Expand Down

0 comments on commit b06258c

Please sign in to comment.