Skip to content

Commit 1b07709

Browse files
committed
---
yaml --- r: 634 b: refs/heads/master c: 974092c h: refs/heads/master v: v3
1 parent d4f3bf4 commit 1b07709

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 4e355aebf7c0987c3d6f66ca0013e7023aa501dd
2+
refs/heads/master: 974092c5265ac6ed500bdf277412461f092fda96

trunk/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] {

trunk/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)