diff options
| -rw-r--r-- | src/libcore/dvec.rs | 8 | ||||
| -rw-r--r-- | src/libcore/sys.rs | 1 | ||||
| -rw-r--r-- | src/libcore/uint-template/uint.rs | 1 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 40 | ||||
| -rw-r--r-- | src/libstd/smallintmap.rs | 2 | ||||
| -rw-r--r-- | src/test/bench/core-vec-append.rs | 4 |
6 files changed, 40 insertions, 16 deletions
diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index ef368fe7a8b..d30179fd881 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -113,6 +113,7 @@ impl extensions<A> for dvec<A> { and return a new vector to replace it with. "] + #[inline(always)] fn swap(f: fn(-[mut A]) -> [mut A]) { self.borrow { |v| self.return(f(v)) } } @@ -136,11 +137,8 @@ impl extensions<A> for dvec<A> { impl extensions<A:copy> for dvec<A> { #[doc = "Append a single item to the end of the list"] fn push(t: A) { - self.swap { |v| - let mut v <- v; - vec::push(v, t); - v - } + self.check_not_borrowed(); + vec::push(self.data, t); } #[doc = "Remove and return the last element"] diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 1e4e5b17bb9..77207d8aebf 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -51,6 +51,7 @@ pure fn get_type_desc<T>() -> *type_desc { } #[doc = "Returns the size of a type"] +#[inline(always)] pure fn size_of<T>() -> uint unsafe { unchecked { rusti::size_of::<T>() } } diff --git a/src/libcore/uint-template/uint.rs b/src/libcore/uint-template/uint.rs index e1bb89c27c4..843215bd4b9 100644 --- a/src/libcore/uint-template/uint.rs +++ b/src/libcore/uint-template/uint.rs @@ -81,6 +81,7 @@ fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { } #[doc = "Returns the smallest power of 2 greater than or equal to `n`"] +#[inline(always)] fn next_power_of_two(n: uint) -> uint { let halfbits: uint = sys::size_of::<uint>() * 4u; let mut tmp: uint = n - 1u; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index a1b2ee23f0f..c029e9f2448 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -92,6 +92,11 @@ native mod rustrt { ++count: libc::size_t) -> *unsafe::vec_repr; } +#[abi = "rust-intrinsic"] +native mod rusti { + fn move_val_init<T>(&dst: T, -src: T); +} + #[doc = "A function used to initialize the elements of a vector"] type init_op<T> = fn(uint) -> T; @@ -392,17 +397,33 @@ fn pop<T>(&v: [const T]) -> T unsafe { #[doc = "Append an element to a vector"] #[inline(always)] fn push<T>(&v: [const T], +initval: T) { - let ln = v.len(); unsafe { - reserve_at_least(v, ln + 1u); - unsafe::set_len(v, ln + 1u); - let p = ptr::mut_addr_of(v[ln]); + let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); + let fill = (**repr).fill; + if (**repr).alloc > fill { + let sz = sys::size_of::<T>(); + (**repr).fill += sz; + let p = ptr::addr_of((**repr).data); + let p = ptr::offset(p, fill) as *mut T; + rusti::move_val_init(*p, initval); + } + else { + push_slow(v, initval); + } + } +} - // FIXME: for performance, try replacing the memmove and <- with a - // memset and unsafe::forget. - ptr::memset(p, 0, 1u); // needed to stop drop glue from running on - // garbage data. - *p = initval; +fn push_slow<T>(&v: [const T], +initval: T) { + unsafe { + let ln = v.len(); + reserve_at_least(v, ln + 1u); + let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); + let fill = (**repr).fill; + let sz = sys::size_of::<T>(); + (**repr).fill += sz; + let p = ptr::addr_of((**repr).data); + let p = ptr::offset(p, fill) as *mut T; + rusti::move_val_init(*p, initval); } } @@ -497,6 +518,7 @@ Sets the element at position `index` to `val`. If `index` is past the end of the vector, expands the vector by replicating `initval` to fill the intervening space. "] +#[inline(always)] fn grow_set<T: copy>(&v: [mut T], index: uint, initval: T, val: T) { if index >= len(v) { grow(v, index - len(v) + 1u, initval); } v[index] = val; diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 1abf54b438d..3a3b90d2513 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -19,6 +19,7 @@ fn mk<T: copy>() -> smallintmap<T> { Add a value to the map. If the map already contains a value for the specified key then the original value is replaced. "] +#[inline(always)] fn insert<T: copy>(self: smallintmap<T>, key: uint, val: T) { self.v.grow_set_elt(key, none, some(val)); } @@ -62,6 +63,7 @@ impl <V: copy> of map::map<uint, V> for smallintmap<V> { } sz } + #[inline(always)] fn insert(+key: uint, +value: V) -> bool { let exists = contains_key(self, key); insert(self, key, value); diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index 9a29671e184..dec12c69aa6 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -7,8 +7,8 @@ import io::writer_util; fn collect_raw(num: uint) -> [uint] { let mut result = []; for uint::range(0u, num) { |i| - result += [i]; - //vec::push(result, i); + //result += [i]; + vec::push(result, i); //result = vec::append(result, [i]); } ret result; |
