summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorEric Holk <eric.holk@gmail.com>2012-07-25 17:29:34 -0700
committerEric Holk <eric.holk@gmail.com>2012-07-25 17:30:13 -0700
commit3aee39a6ec910bde6ae9a5423b11aaaad4a1b089 (patch)
tree7b33b33d6df0ba71edbc1943a6ab0c6177726cff /src/libcore
parent987814f11e4614b8aa712eb19cff78fbbe0d34fa (diff)
downloadrust-3aee39a6ec910bde6ae9a5423b11aaaad4a1b089.tar.gz
rust-3aee39a6ec910bde6ae9a5423b11aaaad4a1b089.zip
Add #[inline(never)], and also fixed inlining on vec::push
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/dvec.rs5
-rw-r--r--src/libcore/vec.rs20
2 files changed, 19 insertions, 6 deletions
diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
index bdbdb6cef16..60cb1b51be6 100644
--- a/src/libcore/dvec.rs
+++ b/src/libcore/dvec.rs
@@ -108,6 +108,11 @@ impl private_methods<A> for dvec<A> {
 // almost nothing works without the copy bound due to limitations
 // around closures.
 impl extensions<A> for dvec<A> {
+    /// Reserves space for N elements
+    fn reserve(count: uint) {
+        vec::reserve(self.data, count)
+    }
+
     /**
      * Swaps out the current vector and hands it off to a user-provided
      * function `f`.  The function should transform it however is desired
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 5aa2f35029a..c07dd9b8224 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -509,10 +509,7 @@ fn push<T>(&v: ~[const T], +initval: T) {
         let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
         let fill = (**repr).fill;
         if (**repr).alloc > fill {
-            (**repr).fill += sys::size_of::<T>();
-            let p = ptr::addr_of((**repr).data);
-            let p = ptr::offset(p, fill) as *mut T;
-            rusti::move_val_init(*p, initval);
+            push_fast(v, initval);
         }
         else {
             push_slow(v, initval);
@@ -520,9 +517,21 @@ fn push<T>(&v: ~[const T], +initval: T) {
     }
 }
 
+// This doesn't bother to make sure we have space.
+#[inline(always)] // really pretty please
+unsafe fn push_fast<T>(&v: ~[const T], +initval: T) {
+    let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v));
+    let fill = (**repr).fill;
+    (**repr).fill += sys::size_of::<T>();
+    let p = ptr::addr_of((**repr).data);
+    let p = ptr::offset(p, fill) as *mut T;
+    rusti::move_val_init(*p, initval);
+}
+
+#[inline(never)]
 fn push_slow<T>(&v: ~[const T], +initval: T) {
     reserve_at_least(v, v.len() + 1u);
-    push(v, initval);
+    unsafe { push_fast(v, initval) }
 }
 
 // Unchecked vector indexing
@@ -644,7 +653,6 @@ fn grow_fn<T>(&v: ~[const T], n: uint, op: init_op<T>) {
  * 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;