Skip to content

Commit 547fd5c

Browse files
committed
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.
2 parents 0a96756 + 77f5da7 commit 547fd5c

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/libcollections/vec.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use alloc::heap::EMPTY;
6565
use core::cmp::Ordering;
6666
use core::fmt;
6767
use core::hash::{self, Hash};
68-
use core::intrinsics::{arith_offset, assume, drop_in_place};
68+
use core::intrinsics::{arith_offset, assume, drop_in_place, needs_drop};
6969
use core::iter::FromIterator;
7070
use core::mem;
7171
use core::ops::{Index, IndexMut, Deref};
@@ -1322,8 +1322,14 @@ impl<T> Drop for Vec<T> {
13221322
// OK because exactly when this stops being a valid assumption, we
13231323
// don't need unsafe_no_drop_flag shenanigans anymore.
13241324
if self.buf.unsafe_no_drop_flag_needs_drop() {
1325-
for x in self.iter_mut() {
1326-
unsafe { drop_in_place(x); }
1325+
unsafe {
1326+
// The branch on needs_drop() is an -O1 performance optimization.
1327+
// Without the branch, dropping Vec<u8> takes linear time.
1328+
if needs_drop::<T>() {
1329+
for x in self.iter_mut() {
1330+
drop_in_place(x);
1331+
}
1332+
}
13271333
}
13281334
}
13291335
// RawVec handles deallocation

0 commit comments

Comments
 (0)