about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-21 16:36:26 +0000
committerbors <bors@rust-lang.org>2015-09-21 16:36:26 +0000
commit547fd5c11e6902e2f9748e7b46893211b36da421 (patch)
tree51df2f4c747f3352bfd0379f1cee358188c6188e
parent0a967561783f093c2b63057283784892e855a408 (diff)
parent77f5da77a91af88130fcff3e726931934c71ba3f (diff)
downloadrust-547fd5c11e6902e2f9748e7b46893211b36da421.tar.gz
rust-547fd5c11e6902e2f9748e7b46893211b36da421.zip
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.
-rw-r--r--src/libcollections/vec.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index c99460a55c9..4110faa41b3 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -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