Skip to content

Commit e027782

Browse files
committed
---
yaml --- r: 113076 b: refs/heads/try c: 5803b10 h: refs/heads/master v: v3
1 parent 401cef4 commit e027782

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: abdacecdf86b4b5a4f432560445a24e1c5f4751b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 922c420fcd4dfbfc7e3bce4dd20d9b17a20b39f3
5-
refs/heads/try: 6d88571910adf2582664da5543700c2d87289b13
5+
refs/heads/try: 5803b1088aefe1e6a8998c4356af2105773e243f
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libstd/slice.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -668,15 +668,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
668668
#[inline]
669669
fn to_owned(&self) -> ~[T] {
670670
let len = self.len();
671-
let mut result = Vec::with_capacity(len);
672-
// Unsafe code so this can be optimised to a memcpy (or something
673-
// similarly fast) when T is Copy. LLVM is easily confused, so any
674-
// extra operations during the loop can prevent this optimisation
671+
let data_size = len.checked_mul(&mem::size_of::<T>());
672+
let data_size = data_size.expect("overflow in to_owned()");
673+
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
674+
let size = size.expect("overflow in to_owned()");
675+
675676
unsafe {
677+
let ret = malloc_raw(size) as *mut RawVec<()>;
678+
679+
(*ret).fill = len * mem::nonzero_size_of::<T>();
680+
(*ret).alloc = len * mem::nonzero_size_of::<T>();
681+
682+
// Be careful with the following loop. We want it to be optimized
683+
// to a memcpy (or something similarly fast) when T is Copy. LLVM
684+
// is easily confused, so any extra operations during the loop can
685+
// prevent this optimization.
676686
let mut i = 0;
677-
let p = result.as_mut_ptr();
678-
// Use try_finally here otherwise the write to length
679-
// inside the loop stops LLVM from optimising this.
687+
let p = &mut (*ret).data as *mut _ as *mut T;
680688
try_finally(
681689
&mut i, (),
682690
|i, ()| while *i < len {
@@ -685,9 +693,15 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
685693
self.unsafe_ref(*i).clone());
686694
*i += 1;
687695
},
688-
|i| result.set_len(*i));
696+
|i| if *i < len {
697+
// we must be failing, clean up after ourselves
698+
for j in range(0, *i as int) {
699+
ptr::read(&*p.offset(j));
700+
}
701+
exchange_free(ret as *u8);
702+
});
703+
cast::transmute(ret)
689704
}
690-
result.move_iter().collect()
691705
}
692706

693707
#[inline(always)]

0 commit comments

Comments
 (0)