Skip to content

Commit c4839f7

Browse files
author
Elliott Slaughter
committed
---
yaml --- r: 23775 b: refs/heads/master c: 9ea4afe h: refs/heads/master i: 23773: e374808 23771: 053f1c5 23767: b0b6bf6 23759: a4be197 23743: 3fb5cc5 v: v3
1 parent dc20272 commit c4839f7

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 3f0d207b3251e598488588765b942bf6b7a4f9bb
2+
refs/heads/master: 9ea4afe5daf359c7022057774f943645d0d32043
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
55
refs/heads/try: ffbe0e0e00374358b789b0037bcb3a577cd218be

trunk/src/libcore/gc.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import stackwalk::Word;
22
import libc::size_t;
3+
import send_map::linear::LinearMap;
34

45
extern mod rustrt {
56
fn rust_annihilate_box(ptr: *Word);
@@ -37,7 +38,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
3738
return None;
3839
}
3940

40-
type Visitor = fn(root: **Word, tydesc: *Word);
41+
type Visitor = fn(root: **Word, tydesc: *Word) -> bool;
4142

4243
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
4344
let fp_bytes: *u8 = unsafe::reinterpret_cast(&fp);
@@ -69,7 +70,7 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
6970
} else {
7071
ptr::null()
7172
};
72-
visitor(root, tydesc);
73+
if !visitor(root, tydesc) { return; }
7374
}
7475
sri += 1;
7576
}
@@ -94,25 +95,25 @@ const need_cleanup: Memory = exchange_heap | stack;
9495

9596
unsafe fn walk_gc_roots(mem: Memory, visitor: Visitor) {
9697
let mut last_ret: *Word = ptr::null();
97-
do stackwalk::walk_stack |frame| {
98+
for stackwalk::walk_stack |frame| {
9899
unsafe {
99100
if ptr::is_not_null(last_ret) {
100101
let sp = is_safe_point(last_ret);
101102
match sp {
102103
Some(sp_info) => {
103-
do walk_safe_point(frame.fp, sp_info) |root, tydesc| {
104+
for walk_safe_point(frame.fp, sp_info) |root, tydesc| {
104105
if ptr::is_null(tydesc) {
105106
// Root is a generic box.
106107
let refcount = **root;
107108
if mem | task_local_heap != 0 && refcount != -1 {
108-
visitor(root, tydesc);
109+
if !visitor(root, tydesc) { return; }
109110
} else if mem | exchange_heap != 0 {
110-
visitor(root, tydesc);
111+
if !visitor(root, tydesc) { return; }
111112
}
112113
} else {
113114
// Root is a non-immediate.
114115
if mem | stack != 0 {
115-
visitor(root, tydesc);
116+
if !visitor(root, tydesc) { return; }
116117
}
117118
}
118119
}
@@ -122,34 +123,42 @@ unsafe fn walk_gc_roots(mem: Memory, visitor: Visitor) {
122123
}
123124
last_ret = *ptr::offset(frame.fp, 1) as *Word;
124125
}
125-
true
126126
}
127127
}
128128

129129
fn gc() {
130130
unsafe {
131-
let mut i = 0;
132-
do walk_gc_roots(task_local_heap) |_root, _tydesc| {
131+
for walk_gc_roots(task_local_heap) |_root, _tydesc| {
133132
// FIXME(#2997): Walk roots and mark them.
134133
io::stdout().write([46]); // .
135-
i += 1;
136134
}
137135
}
138136
}
139137

138+
type RootSet = LinearMap<*Word,()>;
139+
140+
fn RootSet() -> RootSet {
141+
LinearMap()
142+
}
143+
140144
// This should only be called from fail, as it will drop the roots
141145
// which are *live* on the stack, rather than dropping those that are
142146
// dead.
143147
fn cleanup_stack_for_failure() {
144148
unsafe {
145-
let mut i = 0;
146-
do walk_gc_roots(need_cleanup) |root, tydesc| {
149+
let mut roots = ~RootSet();
150+
for walk_gc_roots(need_cleanup) |root, tydesc| {
151+
// Track roots to avoid double frees.
152+
if option::is_some(roots.find(&*root)) {
153+
again;
154+
}
155+
roots.insert(*root, ());
156+
147157
if ptr::is_null(tydesc) {
148158
rustrt::rust_annihilate_box(*root);
149159
} else {
150160
rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t);
151161
}
152-
i += 1;
153162
}
154163
}
155164
}

0 commit comments

Comments
 (0)