Skip to content

Commit 80e66d0

Browse files
committed
---
yaml --- r: 113273 b: refs/heads/snap-stage3 c: 4af8431 h: refs/heads/master i: 113271: 3973c5c v: v3
1 parent 40fa70b commit 80e66d0

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
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: abdacecdf86b4b5a4f432560445a24e1c5f4751b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: bf1e065371f8e50f84318b45fb21a949faa9449f
4+
refs/heads/snap-stage3: 4af84313d67e3062e43c0123093278b1887cac64
55
refs/heads/try: 7c6c492fb2af9a85f21ff952942df3523b22fd17
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/slice.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
315315
#[inline]
316316
fn to_owned(&self) -> ~[T] {
317317
let len = self.len();
318-
let mut result = Vec::with_capacity(len);
319-
// Unsafe code so this can be optimised to a memcpy (or something
320-
// similarly fast) when T is Copy. LLVM is easily confused, so any
321-
// extra operations during the loop can prevent this optimisation
318+
let data_size = len.checked_mul(&mem::size_of::<T>());
319+
let data_size = data_size.expect("overflow in to_owned()");
320+
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
321+
let size = size.expect("overflow in to_owned()");
322+
322323
unsafe {
324+
let ret = malloc_raw(size) as *mut RawVec<()>;
325+
326+
(*ret).fill = len * mem::nonzero_size_of::<T>();
327+
(*ret).alloc = len * mem::nonzero_size_of::<T>();
328+
329+
// Be careful with the following loop. We want it to be optimized
330+
// to a memcpy (or something similarly fast) when T is Copy. LLVM
331+
// is easily confused, so any extra operations during the loop can
332+
// prevent this optimization.
323333
let mut i = 0;
324-
let p = result.as_mut_ptr();
325-
// Use try_finally here otherwise the write to length
326-
// inside the loop stops LLVM from optimising this.
334+
let p = &mut (*ret).data as *mut _ as *mut T;
327335
try_finally(
328336
&mut i, (),
329337
|i, ()| while *i < len {
@@ -332,9 +340,15 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
332340
self.unsafe_ref(*i).clone());
333341
*i += 1;
334342
},
335-
|i| result.set_len(*i));
343+
|i| if *i < len {
344+
// we must be failing, clean up after ourselves
345+
for j in range(0, *i as int) {
346+
ptr::read(&*p.offset(j));
347+
}
348+
exchange_free(ret as *u8);
349+
});
350+
cast::transmute(ret)
336351
}
337-
result.move_iter().collect()
338352
}
339353

340354
#[inline(always)]

0 commit comments

Comments
 (0)