aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/_vec.rs5
-rw-r--r--src/test/run-pass/vec-append.rs63
2 files changed, 68 insertions, 0 deletions
diff --git a/src/lib/_vec.rs b/src/lib/_vec.rs
index 5f1d2baa..39dc8617 100644
--- a/src/lib/_vec.rs
+++ b/src/lib/_vec.rs
@@ -29,6 +29,11 @@ fn alloc[T](uint n_elts) -> vec[T] {
ret rustrt.vec_alloc[vec[T], T](n_elts);
}
+fn refcount[T](vec[T] v) -> uint {
+ // -1 because calling this function incremented the refcount.
+ ret rustrt.refcount[T](v) - 1u;
+}
+
type init_op[T] = fn(uint i) -> T;
fn init_fn[T](&init_op[T] op, uint n_elts) -> vec[T] {
diff --git a/src/test/run-pass/vec-append.rs b/src/test/run-pass/vec-append.rs
index e52c6283..5b0a92ae 100644
--- a/src/test/run-pass/vec-append.rs
+++ b/src/test/run-pass/vec-append.rs
@@ -1,5 +1,9 @@
// -*- rust -*-
+use std;
+import std._str;
+import std._vec;
+
fn fast_growth() {
let vec[int] v = vec(1,2,3,4,5);
v += vec(6,7,8,9,0);
@@ -19,7 +23,66 @@ fn slow_growth() {
check (v.(0) == 17);
}
+fn slow_growth2_helper(str s) { // ref up: s
+
+ obj acc(vec[str] v) {
+ fn add(&str s) { v += vec(s); }
+ }
+
+ let str ss = s; // ref up: s
+ let str mumble = "mrghrm"; // ref up: mumble
+
+ {
+ /**
+ * Within this block, mumble goes into a vec that is referenced
+ * both by the local slot v and the acc's v data field. When we
+ * add(s) on the acc, its v undergoes a slow append (allocate a
+ * new vec, copy over existing elements). Here we're testing to
+ * see that this slow path goes over well. In particular, the
+ * copy of existing elements should increment the ref count of
+ * mumble, the existing str in the originally- shared vec.
+ */
+ let vec[str] v = vec(mumble); // ref up: v, mumble
+ let acc a = acc(v); // ref up: a, v
+
+ log _vec.refcount[str](v);
+ check (_vec.refcount[str](v) == 2u);
+
+ a.add(s); // ref up: mumble, s. ref down: v
+
+ log _vec.refcount[str](v);
+ log _str.refcount(s);
+ log _str.refcount(mumble);
+
+ check (_vec.refcount[str](v) == 1u);
+ check (_str.refcount(s) == 4u);
+ check (_str.refcount(mumble) == 3u);
+
+ log v.(0);
+ log _vec.len[str](v);
+ check (_str.eq(v.(0), mumble));
+ check (_vec.len[str](v) == 1u);
+ } // ref down: a, mumble, s, v
+
+ log _str.refcount(s);
+ log _str.refcount(mumble);
+
+ check (_str.refcount(s) == 3u);
+ check (_str.refcount(mumble) == 1u);
+
+ log mumble;
+ log ss;
+} // ref down
+
+fn slow_growth2() {
+ let str s = "hi"; // ref up: s
+ slow_growth2_helper(s);
+ log _str.refcount(s);
+ check (_str.refcount(s) == 1u);
+}
+
fn main() {
fast_growth();
slow_growth();
+ slow_growth2();
}