Skip to content

Commit 974092c

Browse files
committed
Test multi-ref'ed vec growth more seriously than before.
1 parent 4e355ae commit 974092c

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/lib/_vec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ fn alloc[T](uint n_elts) -> vec[T] {
2929
ret rustrt.vec_alloc[vec[T], T](n_elts);
3030
}
3131

32+
fn refcount[T](vec[T] v) -> uint {
33+
// -1 because calling this function incremented the refcount.
34+
ret rustrt.refcount[T](v) - 1u;
35+
}
36+
3237
type init_op[T] = fn(uint i) -> T;
3338

3439
fn init_fn[T](&init_op[T] op, uint n_elts) -> vec[T] {

src/test/run-pass/vec-append.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// -*- rust -*-
22

3+
use std;
4+
import std._str;
5+
import std._vec;
6+
37
fn fast_growth() {
48
let vec[int] v = vec(1,2,3,4,5);
59
v += vec(6,7,8,9,0);
@@ -19,7 +23,66 @@ fn slow_growth() {
1923
check (v.(0) == 17);
2024
}
2125

26+
fn slow_growth2_helper(str s) { // ref up: s
27+
28+
obj acc(vec[str] v) {
29+
fn add(&str s) { v += vec(s); }
30+
}
31+
32+
let str ss = s; // ref up: s
33+
let str mumble = "mrghrm"; // ref up: mumble
34+
35+
{
36+
/**
37+
* Within this block, mumble goes into a vec that is referenced
38+
* both by the local slot v and the acc's v data field. When we
39+
* add(s) on the acc, its v undergoes a slow append (allocate a
40+
* new vec, copy over existing elements). Here we're testing to
41+
* see that this slow path goes over well. In particular, the
42+
* copy of existing elements should increment the ref count of
43+
* mumble, the existing str in the originally- shared vec.
44+
*/
45+
let vec[str] v = vec(mumble); // ref up: v, mumble
46+
let acc a = acc(v); // ref up: a, v
47+
48+
log _vec.refcount[str](v);
49+
check (_vec.refcount[str](v) == 2u);
50+
51+
a.add(s); // ref up: mumble, s. ref down: v
52+
53+
log _vec.refcount[str](v);
54+
log _str.refcount(s);
55+
log _str.refcount(mumble);
56+
57+
check (_vec.refcount[str](v) == 1u);
58+
check (_str.refcount(s) == 4u);
59+
check (_str.refcount(mumble) == 3u);
60+
61+
log v.(0);
62+
log _vec.len[str](v);
63+
check (_str.eq(v.(0), mumble));
64+
check (_vec.len[str](v) == 1u);
65+
} // ref down: a, mumble, s, v
66+
67+
log _str.refcount(s);
68+
log _str.refcount(mumble);
69+
70+
check (_str.refcount(s) == 3u);
71+
check (_str.refcount(mumble) == 1u);
72+
73+
log mumble;
74+
log ss;
75+
} // ref down
76+
77+
fn slow_growth2() {
78+
let str s = "hi"; // ref up: s
79+
slow_growth2_helper(s);
80+
log _str.refcount(s);
81+
check (_str.refcount(s) == 1u);
82+
}
83+
2284
fn main() {
2385
fast_growth();
2486
slow_growth();
87+
slow_growth2();
2588
}

0 commit comments

Comments
 (0)