mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #107167 - the8472:rawvec-simpler-layout, r=thomcc
simplify layout calculations in rawvec The use of `Layout::array` was introduced in #83706 which lead to a [perf regression](https://github.com/rust-lang/rust/pull/83706#issuecomment-1048377719). This PR basically reverts that change since rust currently only supports stride == size types, but to be on the safe side it leaves a const-assert there to make sure this gets caught if those assumptions ever change.
This commit is contained in:
commit
8dabf5da9e
@ -241,10 +241,15 @@ impl<T, A: Allocator> RawVec<T, A> {
|
||||
if T::IS_ZST || self.cap == 0 {
|
||||
None
|
||||
} else {
|
||||
// We have an allocated chunk of memory, so we can bypass runtime
|
||||
// checks to get our current layout.
|
||||
// We could use Layout::array here which ensures the absence of isize and usize overflows
|
||||
// and could hypothetically handle differences between stride and size, but this memory
|
||||
// has already been allocated so we know it can't overflow and currently rust does not
|
||||
// support such types. So we can do better by skipping some checks and avoid an unwrap.
|
||||
let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };
|
||||
unsafe {
|
||||
let layout = Layout::array::<T>(self.cap).unwrap_unchecked();
|
||||
let align = mem::align_of::<T>();
|
||||
let size = mem::size_of::<T>().unchecked_mul(self.cap);
|
||||
let layout = Layout::from_size_align_unchecked(size, align);
|
||||
Some((self.ptr.cast().into(), layout))
|
||||
}
|
||||
}
|
||||
@ -426,11 +431,13 @@ impl<T, A: Allocator> RawVec<T, A> {
|
||||
assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
|
||||
|
||||
let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
|
||||
|
||||
// See current_memory() why this assert is here
|
||||
let _: () = const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };
|
||||
let ptr = unsafe {
|
||||
// `Layout::array` cannot overflow here because it would have
|
||||
// overflowed earlier when capacity was larger.
|
||||
let new_layout = Layout::array::<T>(cap).unwrap_unchecked();
|
||||
let new_size = mem::size_of::<T>().unchecked_mul(cap);
|
||||
let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
|
||||
self.alloc
|
||||
.shrink(ptr, layout, new_layout)
|
||||
.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
|
||||
|
@ -1,2 +1,2 @@
|
||||
thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:518:5
|
||||
thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:525:5
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
Loading…
Reference in New Issue
Block a user