Skip to content

Commit 7e210a8

Browse files
author
blake2-ppc
committed
std: Replace for with do { .. } expr in std::gc
Change all users of old-style for with internal iterators to using `do`-loops. The code in stackwalk.rs does not actually implement the looping protocol (no break on return false). The code in gc.rs does not use loop breaks, nor does any code using it. We remove the capacity to break from the loops in std::gc and implement the walks using `do { .. }` expressions. No behavior change.
1 parent e5a64f2 commit 7e210a8

File tree

2 files changed

+52
-62
lines changed

2 files changed

+52
-62
lines changed

src/libstd/gc.rs

Lines changed: 49 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
121121
return None;
122122
}
123123

124-
type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool;
124+
type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc);
125125

126126
// Walks the list of roots for the given safe point, and calls visitor
127127
// on each root.
128-
unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
128+
unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
129129
let fp_bytes = fp as *u8;
130130
let sp_meta = sp.sp_meta as *u32;
131131

@@ -151,7 +151,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
151151
} else {
152152
ptr::null()
153153
};
154-
if !visitor(root, tydesc) { return false; }
154+
visitor(root, tydesc);
155155
}
156156
sri += 1;
157157
}
@@ -164,10 +164,9 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
164164
}
165165
rri += 1;
166166
}
167-
return true;
168167
}
169168

170-
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
169+
unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
171170
_walk_safe_point(fp, sp, visitor)
172171
}
173172

@@ -223,15 +222,15 @@ static need_cleanup: Memory = exchange_heap | stack;
223222

224223
// Walks stack, searching for roots of the requested type, and passes
225224
// each root to the visitor.
226-
unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool {
225+
unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
227226
let mut segment = rustrt::rust_get_stack_segment();
228227
let mut last_ret: *Word = ptr::null();
229228
// To avoid collecting memory used by the GC itself, skip stack
230229
// frames until past the root GC stack frame. The root GC stack
231230
// frame is marked by a sentinel, which is a box pointer stored on
232231
// the stack.
233232
let mut reached_sentinel = ptr::is_null(sentinel);
234-
for walk_stack |frame| {
233+
do walk_stack |frame| {
235234
let pc = last_ret;
236235
let Segment {segment: next_segment, boundary: boundary} =
237236
find_segment_for_frame(frame.fp, segment);
@@ -248,53 +247,46 @@ unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> boo
248247
let ret_offset = if boundary { 4 } else { 1 };
249248
last_ret = *ptr::offset(frame.fp, ret_offset as int) as *Word;
250249

251-
if ptr::is_null(pc) {
252-
loop;
253-
}
254-
255-
let mut delay_reached_sentinel = reached_sentinel;
256-
let sp = is_safe_point(pc);
257-
match sp {
258-
Some(sp_info) => {
259-
for walk_safe_point(frame.fp, sp_info) |root, tydesc| {
260-
// Skip roots until we see the sentinel.
261-
if !reached_sentinel {
262-
if root == sentinel {
263-
delay_reached_sentinel = true;
264-
}
265-
loop;
266-
}
267-
268-
// Skip null pointers, which can occur when a
269-
// unique pointer has already been freed.
270-
if ptr::is_null(*root) {
271-
loop;
272-
}
273-
274-
if ptr::is_null(tydesc) {
275-
// Root is a generic box.
276-
let refcount = **root;
277-
if mem | task_local_heap != 0 && refcount != -1 {
278-
if !visitor(root, tydesc) { return false; }
279-
} else if mem | exchange_heap != 0 && refcount == -1 {
280-
if !visitor(root, tydesc) { return false; }
281-
}
282-
} else {
283-
// Root is a non-immediate.
284-
if mem | stack != 0 {
285-
if !visitor(root, tydesc) { return false; }
250+
if !ptr::is_null(pc) {
251+
252+
let mut delay_reached_sentinel = reached_sentinel;
253+
let sp = is_safe_point(pc);
254+
match sp {
255+
Some(sp_info) => {
256+
do walk_safe_point(frame.fp, sp_info) |root, tydesc| {
257+
// Skip roots until we see the sentinel.
258+
if !reached_sentinel && root == sentinel {
259+
delay_reached_sentinel = true;
260+
}
261+
262+
// Skip null pointers, which can occur when a
263+
// unique pointer has already been freed.
264+
if reached_sentinel && !ptr::is_null(*root) {
265+
if ptr::is_null(tydesc) {
266+
// Root is a generic box.
267+
let refcount = **root;
268+
if mem | task_local_heap != 0 && refcount != -1 {
269+
visitor(root, tydesc);
270+
} else if mem | exchange_heap != 0 && refcount == -1 {
271+
visitor(root, tydesc);
272+
}
273+
} else {
274+
// Root is a non-immediate.
275+
if mem | stack != 0 {
276+
visitor(root, tydesc);
277+
}
278+
}
279+
}
286280
}
287281
}
282+
None => ()
288283
}
289-
}
290-
None => ()
284+
reached_sentinel = delay_reached_sentinel;
291285
}
292-
reached_sentinel = delay_reached_sentinel;
293286
}
294-
return true;
295287
}
296288

297-
unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) -> bool {
289+
unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
298290
_walk_gc_roots(mem, sentinel, visitor)
299291
}
300292
pub fn gc() {
@@ -304,7 +296,7 @@ pub fn gc() {
304296
return;
305297
}
306298

307-
for walk_gc_roots(task_local_heap, ptr::null()) |_root, _tydesc| {
299+
do walk_gc_roots(task_local_heap, ptr::null()) |_root, _tydesc| {
308300
// FIXME(#2997): Walk roots and mark them.
309301
io::stdout().write([46]); // .
310302
}
@@ -349,18 +341,17 @@ pub fn cleanup_stack_for_failure() {
349341
};
350342

351343
let mut roots = HashSet::new();
352-
for walk_gc_roots(need_cleanup, sentinel) |root, tydesc| {
344+
do walk_gc_roots(need_cleanup, sentinel) |root, tydesc| {
353345
// Track roots to avoid double frees.
354-
if roots.contains(&*root) {
355-
loop;
356-
}
357-
roots.insert(*root);
346+
if !roots.contains(&*root) {
347+
roots.insert(*root);
358348

359-
if ptr::is_null(tydesc) {
360-
// FIXME #4420: Destroy this box
361-
// FIXME #4330: Destroy this box
362-
} else {
363-
((*tydesc).drop_glue)(*root as *i8);
349+
if ptr::is_null(tydesc) {
350+
// FIXME #4420: Destroy this box
351+
// FIXME #4330: Destroy this box
352+
} else {
353+
((*tydesc).drop_glue)(*root as *i8);
354+
}
364355
}
365356
}
366357
}

src/libstd/stackwalk.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub fn Frame(fp: *Word) -> Frame {
2525
}
2626
}
2727

28-
pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool {
28+
pub fn walk_stack(visit: &fn(Frame)) {
2929

3030
debug!("beginning stack walk");
3131

@@ -51,12 +51,11 @@ pub fn walk_stack(visit: &fn(Frame) -> bool) -> bool {
5151
}
5252
}
5353
}
54-
return true;
5554
}
5655

5756
#[test]
5857
fn test_simple() {
59-
for walk_stack |_frame| {
58+
do walk_stack |_frame| {
6059
}
6160
}
6261

@@ -65,7 +64,7 @@ fn test_simple_deep() {
6564
fn run(i: int) {
6665
if i == 0 { return }
6766

68-
for walk_stack |_frame| {
67+
do walk_stack |_frame| {
6968
// Would be nice to test something here...
7069
}
7170
run(i - 1);

0 commit comments

Comments
 (0)