Skip to content

Commit 429bf36

Browse files
committed
---
yaml --- r: 151453 b: refs/heads/try2 c: 4af8431 h: refs/heads/master i: 151451: 7606b3a v: v3
1 parent 96e5546 commit 429bf36

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
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: bf1e065371f8e50f84318b45fb21a949faa9449f
8+
refs/heads/try2: 4af84313d67e3062e43c0123093278b1887cac64
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/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)