Skip to content

Commit e6f1f04

Browse files
committed
Auto merge of #92220 - nnethercote:RawVec-dont-recompute-capacity, r=joshtriplett
RawVec: don't recompute capacity after allocating. Currently it sets the capacity to `ptr.len() / mem::size_of::<T>()` after any buffer allocation/reallocation. This would be useful if allocators ever returned a `NonNull<[u8]>` with a size larger than requested. But this never happens, so it's not useful. Removing this slightly reduces the size of generated LLVM IR, and slightly speeds up the hot path of `RawVec` growth. r? `@ghost`
2 parents d6d12b6 + 8217138 commit e6f1f04

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

Diff for: library/alloc/src/raw_vec.rs

+18-17
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,12 @@ impl<T, A: Allocator> RawVec<T, A> {
190190
Err(_) => handle_alloc_error(layout),
191191
};
192192

193+
// Allocators currently return a `NonNull<[u8]>` whose length
194+
// matches the size requested. If that ever changes, the capacity
195+
// here should change to `ptr.len() / mem::size_of::<T>()`.
193196
Self {
194197
ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
195-
cap: Self::capacity_from_bytes(ptr.len()),
198+
cap: capacity,
196199
alloc,
197200
}
198201
}
@@ -337,7 +340,7 @@ impl<T, A: Allocator> RawVec<T, A> {
337340
if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) }
338341
}
339342

340-
/// Shrinks the allocation down to the specified amount. If the given amount
343+
/// Shrinks the buffer down to the specified capacity. If the given amount
341344
/// is 0, actually completely deallocates.
342345
///
343346
/// # Panics
@@ -348,8 +351,8 @@ impl<T, A: Allocator> RawVec<T, A> {
348351
///
349352
/// Aborts on OOM.
350353
#[cfg(not(no_global_oom_handling))]
351-
pub fn shrink_to_fit(&mut self, amount: usize) {
352-
handle_reserve(self.shrink(amount));
354+
pub fn shrink_to_fit(&mut self, cap: usize) {
355+
handle_reserve(self.shrink(cap));
353356
}
354357
}
355358

@@ -360,14 +363,12 @@ impl<T, A: Allocator> RawVec<T, A> {
360363
additional > self.capacity().wrapping_sub(len)
361364
}
362365

363-
fn capacity_from_bytes(excess: usize) -> usize {
364-
debug_assert_ne!(mem::size_of::<T>(), 0);
365-
excess / mem::size_of::<T>()
366-
}
367-
368-
fn set_ptr(&mut self, ptr: NonNull<[u8]>) {
366+
fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) {
367+
// Allocators currently return a `NonNull<[u8]>` whose length matches
368+
// the size requested. If that ever changes, the capacity here should
369+
// change to `ptr.len() / mem::size_of::<T>()`.
369370
self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) };
370-
self.cap = Self::capacity_from_bytes(ptr.len());
371+
self.cap = cap;
371372
}
372373

373374
// This method is usually instantiated many times. So we want it to be as
@@ -399,7 +400,7 @@ impl<T, A: Allocator> RawVec<T, A> {
399400

400401
// `finish_grow` is non-generic over `T`.
401402
let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
402-
self.set_ptr(ptr);
403+
self.set_ptr_and_cap(ptr, cap);
403404
Ok(())
404405
}
405406

@@ -418,23 +419,23 @@ impl<T, A: Allocator> RawVec<T, A> {
418419

419420
// `finish_grow` is non-generic over `T`.
420421
let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
421-
self.set_ptr(ptr);
422+
self.set_ptr_and_cap(ptr, cap);
422423
Ok(())
423424
}
424425

425-
fn shrink(&mut self, amount: usize) -> Result<(), TryReserveError> {
426-
assert!(amount <= self.capacity(), "Tried to shrink to a larger capacity");
426+
fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
427+
assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
427428

428429
let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
429-
let new_size = amount * mem::size_of::<T>();
430+
let new_size = cap * mem::size_of::<T>();
430431

431432
let ptr = unsafe {
432433
let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
433434
self.alloc
434435
.shrink(ptr, layout, new_layout)
435436
.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
436437
};
437-
self.set_ptr(ptr);
438+
self.set_ptr_and_cap(ptr, cap);
438439
Ok(())
439440
}
440441
}

0 commit comments

Comments
 (0)