Skip to content

Commit 616f4d8

Browse files
committed
Auto merge of #117503 - kornelski:hint-try-reserved, r=<try>
Hint optimizer about try-reserved capacity This is #116568, but limited only to the less-common `try_reserve` functions to reduce bloat in debug binaries from debug info, while still addressing the main use-case #116570
2 parents b20f40d + 029fbd6 commit 616f4d8

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

library/alloc/src/raw_vec.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,13 @@ impl<T, A: Allocator> RawVec<T, A> {
305305
/// The same as `reserve`, but returns on errors instead of panicking or aborting.
306306
pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
307307
if self.needs_to_grow(len, additional) {
308-
self.grow_amortized(len, additional)
309-
} else {
310-
Ok(())
308+
self.grow_amortized(len, additional)?;
309+
}
310+
unsafe {
311+
// Inform the optimizer that the reservation has succeeded or wasn't needed
312+
core::intrinsics::assume(!self.needs_to_grow(len, additional));
311313
}
314+
Ok(())
312315
}
313316

314317
/// Ensures that the buffer contains at least enough space to hold `len +
@@ -339,7 +342,14 @@ impl<T, A: Allocator> RawVec<T, A> {
339342
len: usize,
340343
additional: usize,
341344
) -> Result<(), TryReserveError> {
342-
if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) }
345+
if self.needs_to_grow(len, additional) {
346+
self.grow_exact(len, additional)?;
347+
}
348+
unsafe {
349+
// Inform the optimizer that the reservation has succeeded or wasn't needed
350+
core::intrinsics::assume(!self.needs_to_grow(len, additional));
351+
}
352+
Ok(())
343353
}
344354

345355
/// Shrinks the buffer down to the specified capacity. If the given amount

tests/codegen/vec-reserve-extend.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// compile-flags: -O
2+
3+
#![crate_type = "lib"]
4+
5+
// CHECK-LABEL: @should_reserve_once
6+
#[no_mangle]
7+
pub fn should_reserve_once(v: &mut Vec<u8>) {
8+
// CHECK: tail call void @llvm.assume
9+
v.try_reserve(3).unwrap();
10+
// CHECK-NOT: call {{.*}}reserve
11+
// CHECK-NOT: call {{.*}}do_reserve_and_handle
12+
// CHECK-NOT: call {{.*}}__rust_alloc(
13+
v.extend([1, 2, 3]);
14+
}
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
thread 'main' panicked at library/alloc/src/raw_vec.rs:535:5:
1+
thread 'main' panicked at library/alloc/src/raw_vec.rs:545:5:
22
capacity overflow
33
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

0 commit comments

Comments
 (0)