From c0f8b085942c0c914c3c9d175303c23e1b4158e3 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 2 Mar 2016 17:46:54 +0100 Subject: [PATCH 1/3] Use ptr::drop_in_place in Vec::drop Directly use the drop glue for [T]. Still optimizes out in -O1 like with the `needs_drop` intrinsic. --- src/libcollections/vec.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index ae442e155c0d0..e010c32f8eac0 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -66,7 +66,7 @@ use borrow::ToOwned; use core::cmp::Ordering; use core::fmt; use core::hash::{self, Hash}; -use core::intrinsics::{arith_offset, assume, needs_drop}; +use core::intrinsics::{arith_offset, assume}; use core::iter::FromIterator; use core::mem; use core::ops::{Index, IndexMut}; @@ -1471,13 +1471,8 @@ impl Drop for Vec { fn drop(&mut self) { if self.buf.unsafe_no_drop_flag_needs_drop() { unsafe { - // The branch on needs_drop() is an -O1 performance optimization. - // Without the branch, dropping Vec takes linear time. - if needs_drop::() { - for x in self.iter_mut() { - ptr::drop_in_place(x); - } - } + // use drop for [T] + ptr::drop_in_place(&mut self[..]); } } // RawVec handles deallocation From 1da364e98f46c828e5746be299b58b995e5f5007 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 2 Mar 2016 17:48:50 +0100 Subject: [PATCH 2/3] Use ptr::drop_in_place in Vec::truncate --- src/libcollections/vec.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e010c32f8eac0..efcb5d2ceb3aa 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -497,10 +497,11 @@ impl Vec { unsafe { // drop any extra elements while len < self.len { - // decrement len before the read(), so a panic on Drop doesn't - // re-drop the just-failed value. + // decrement len before the drop_in_place(), so a panic on Drop + // doesn't re-drop the just-failed value. self.len -= 1; - ptr::read(self.get_unchecked(self.len)); + let len = self.len; + ptr::drop_in_place(self.get_unchecked_mut(len)); } } } From 7ceafaee4f3d8ed2268b1659dd99a541d71689a3 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 2 Mar 2016 17:54:43 +0100 Subject: [PATCH 3/3] Use ptr::drop_in_place in VecDeque::drop Just like for Vec. This should benefit both non-optimized and optimized performance. Non-optimized since the intrinsic drop_in_place is easily removed, and optimized because iterating the slices is more efficient than using the VecDeque iterators. --- src/libcollections/vec_deque.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index f34fe2da7e84b..3e48f14d387ff 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -70,7 +70,12 @@ impl Clone for VecDeque { impl Drop for VecDeque { #[unsafe_destructor_blind_to_params] fn drop(&mut self) { - self.clear(); + let (front, back) = self.as_mut_slices(); + unsafe { + // use drop for [T] + ptr::drop_in_place(front); + ptr::drop_in_place(back); + } // RawVec handles deallocation } }