diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
index bdbdb6cef16b..60cb1b51be68 100644
--- a/src/libcore/dvec.rs
+++ b/src/libcore/dvec.rs
@@ -108,6 +108,11 @@ impl private_methods for dvec {
// almost nothing works without the copy bound due to limitations
// around closures.
impl extensions for dvec {
+ /// 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 5aa2f35029ab..c07dd9b8224c 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -509,10 +509,7 @@ fn push(&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::();
- 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(&v: ~[const T], +initval: T) {
}
}
+// This doesn't bother to make sure we have space.
+#[inline(always)] // really pretty please
+unsafe fn push_fast(&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::();
+ 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(&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(&v: ~[const T], n: uint, op: init_op) {
* of the vector, expands the vector by replicating `initval` to fill the
* intervening space.
*/
-#[inline(always)]
fn grow_set(&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 112a55ab67d8..09f14f4f63e6 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -17,7 +17,8 @@ enum smallintmap {
/// Create a smallintmap
fn mk() -> smallintmap {
- ret smallintmap_(@{v: dvec()});
+ let v = dvec();
+ ret smallintmap_(@{v: v});
}
/**
@@ -26,6 +27,7 @@ fn mk() -> smallintmap {
*/
#[inline(always)]
fn insert(self: smallintmap, key: uint, val: T) {
+ //#error("inserting key %?", key);
self.v.grow_set_elt(key, none, some(val));
}
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 859bc70bfd64..4587a5b8b297 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -364,7 +364,8 @@ fn foreign_abi(attrs: ~[ast::attribute]) -> either<~str, ast::foreign_abi> {
enum inline_attr {
ia_none,
ia_hint,
- ia_always
+ ia_always,
+ ia_never,
}
/// True if something like #[inline] is found in the list of attrs.
@@ -376,6 +377,9 @@ fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
ast::meta_list(@~"inline", items) {
if !vec::is_empty(find_meta_items_by_name(items, ~"always")) {
ia_always
+ } else if !vec::is_empty(
+ find_meta_items_by_name(items, ~"never")) {
+ ia_never
} else {
ia_hint
}
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 69e97f7e9db6..b2847b3acc53 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -545,8 +545,8 @@ fn purity_fn_family(p: purity) -> char {
fn should_inline(attrs: ~[attribute]) -> bool {
alt attr::find_inline_attr(attrs) {
- attr::ia_none { false }
- attr::ia_hint | attr::ia_always { true }
+ attr::ia_none | attr::ia_never { false }
+ attr::ia_hint | attr::ia_always { true }
}
}
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 209bb6ee7c2c..94a4a30021db 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -456,6 +456,7 @@ fn set_inline_hint_if_appr(attrs: ~[ast::attribute],
alt attr::find_inline_attr(attrs) {
attr::ia_hint { set_inline_hint(llfn); }
attr::ia_always { set_always_inline(llfn); }
+ attr::ia_never { set_no_inline(llfn); }
attr::ia_none { /* fallthrough */ }
}
}