diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/slice.rs | 25 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 11 |
2 files changed, 19 insertions, 17 deletions
diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs index f4f97ea8c92..153e21c780c 100644 --- a/src/libstd/slice.rs +++ b/src/libstd/slice.rs @@ -762,18 +762,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] { fn to_owned(&self) -> ~[T] { let len = self.len(); let mut result = with_capacity(len); + // Unsafe code so this can be optimised to a memcpy (or something + // similarly fast) when T is Copy. LLVM is easily confused, so any + // extra operations during the loop can prevent this optimisation unsafe { - // Unsafe code so this can be optimised to a memcpy (or something - // similarly fast) when T is Copy. LLVM is easily confused, so any - // extra operations during the loop can prevent this optimisation - result.set_len(len); let mut i = 0; - while i < len { - mem::move_val_init( - result.unsafe_mut_ref(i), - self.unsafe_ref(i).clone()); - i = i + 1; - } + let p = result.as_mut_ptr(); + // Use try_finally here otherwise the write to length + // inside the loop stops LLVM from optimising this. + try_finally( + &mut i, (), + |i, ()| while *i < len { + mem::move_val_init( + &mut(*p.offset(*i as int)), + self.unsafe_ref(*i).clone()); + *i += 1; + }, + |i| result.set_len(*i)); } result } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 034d53aa78b..96cbac8869e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -313,21 +313,18 @@ impl<T:Clone> Clone for Vec<T> { fn clone(&self) -> Vec<T> { let len = self.len; let mut vector = Vec::with_capacity(len); - vector.len = len; // Unsafe code so this can be optimised to a memcpy (or something // similarly fast) when T is Copy. LLVM is easily confused, so any // extra operations during the loop can prevent this optimisation { - let slice = vector.as_mut_slice(); let this_slice = self.as_slice(); - let mut i = 0; - while i < len { + while vector.len < len { unsafe { mem::move_val_init( - slice.unsafe_mut_ref(i), - this_slice.unsafe_ref(i).clone()); + vector.as_mut_slice().unsafe_mut_ref(vector.len), + this_slice.unsafe_ref(vector.len).clone()); } - i = i + 1; + vector.len += 1; } } vector |
