mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-14 07:53:24 +00:00
Auto merge of #28531 - whitequark:patch-1, r=Gankro
With -O2, LLVM's inliner can remove this code, but this does not happen with -O1 and lower. As a result, dropping Vec<u8> was linear with length, resulting in abysmal performance for large buffers. See issue #24280.
This commit is contained in:
commit
547fd5c11e
@ -65,7 +65,7 @@ use alloc::heap::EMPTY;
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
use core::intrinsics::{arith_offset, assume, drop_in_place};
|
||||
use core::intrinsics::{arith_offset, assume, drop_in_place, needs_drop};
|
||||
use core::iter::FromIterator;
|
||||
use core::mem;
|
||||
use core::ops::{Index, IndexMut, Deref};
|
||||
@ -1322,8 +1322,14 @@ impl<T> Drop for Vec<T> {
|
||||
// OK because exactly when this stops being a valid assumption, we
|
||||
// don't need unsafe_no_drop_flag shenanigans anymore.
|
||||
if self.buf.unsafe_no_drop_flag_needs_drop() {
|
||||
for x in self.iter_mut() {
|
||||
unsafe { drop_in_place(x); }
|
||||
unsafe {
|
||||
// The branch on needs_drop() is an -O1 performance optimization.
|
||||
// Without the branch, dropping Vec<u8> takes linear time.
|
||||
if needs_drop::<T>() {
|
||||
for x in self.iter_mut() {
|
||||
drop_in_place(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// RawVec handles deallocation
|
||||
|
Loading…
Reference in New Issue
Block a user