Skip to content

Commit b2035e0

Browse files
refactor(gc): Deduplicate IterFrame and SyncFrame val traversal.
1 parent 60f717b commit b2035e0

3 files changed

Lines changed: 24 additions & 38 deletions

File tree

compiler/src/modules/vm/gc.rs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,7 @@ impl<'a> VM<'a> {
66
/* Mark all reachable roots then sweep; non-heap Vals are no-op to mark. */
77
pub(crate) fn collect(&mut self, current_slots: &[Val]) {
88
for &v in &self.stack { self.heap.mark(v); }
9-
for sf in &self.pending_sync_frames {
10-
for &v in &sf.slots { self.heap.mark(v); }
11-
for &v in &sf.stack_delta { self.heap.mark(v); }
12-
for fr in &sf.iter_delta {
13-
match fr {
14-
IterFrame::Seq { items, .. } => for &v in items { self.heap.mark(v); },
15-
IterFrame::Coroutine(v) => self.heap.mark(*v),
16-
IterFrame::UserDefined(v) => self.heap.mark(*v),
17-
IterFrame::Range { .. } => {}
18-
}
19-
}
20-
}
9+
for sf in &self.pending_sync_frames { sf.for_each_val(&mut |v| heap.mark(v)); }
2110
for &v in &self.with_stack { self.heap.mark(v); }
2211
for &v in &self.yields { self.heap.mark(v); }
2312
for &v in &self.event_queue { self.heap.mark(v); }
@@ -40,16 +29,9 @@ impl<'a> VM<'a> {
4029
}
4130
for &v in self.globals.values() { self.heap.mark(v); }
4231
for &v in self.module_state.values() { self.heap.mark(v); }
43-
for frame in &self.iter_stack {
44-
match frame {
45-
IterFrame::Seq { items, .. } => {
46-
for &v in items { self.heap.mark(v); }
47-
}
48-
IterFrame::Coroutine(v) => self.heap.mark(*v),
49-
IterFrame::UserDefined(v) => self.heap.mark(*v),
50-
IterFrame::Range { .. } => {}
51-
}
52-
}
32+
let heap = &mut self.heap; // split borrow: lets closures take &mut heap while iterating other fields
33+
for frame in &self.iter_stack { frame.for_each_val(&mut |v| heap.mark(v)); }
34+
for sf in &self.pending_sync_frames { sf.for_each_val(&mut |v| heap.mark(v)); }
5335
for cache in self.opcode_caches.values() {
5436
if let Some(consts) = cache.const_vals_opt() {
5537
for &v in consts { self.heap.mark(v); }

compiler/src/modules/vm/types/coro.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,22 @@ impl IterFrame {
106106
}
107107
}
108108
}
109+
110+
/* Visit each Val in this frame; Range holds none. */
111+
pub(crate) fn for_each_val(&self, f: &mut impl FnMut(Val)) {
112+
match self {
113+
IterFrame::Seq { items, .. } => for &v in items { f(v); },
114+
Self::Coroutine(v) | Self::UserDefined(v) => f(*v),
115+
IterFrame::Range { .. } => {}
116+
}
117+
}
118+
}
119+
120+
impl SyncFrame {
121+
/* Visit all Vals across slots, stack delta, and iter frames. */
122+
pub(crate) fn for_each_val(&self, f: &mut impl FnMut(Val)) {
123+
for &v in &self.slots { f(v); }
124+
for &v in &self.stack_delta { f(v); }
125+
for fr in &self.iter_delta { fr.for_each_val(f); }
126+
}
109127
}

compiler/src/modules/vm/types/mod.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -315,22 +315,8 @@ pub(crate) fn for_each_val(obj: &HeapObj, mut f: impl FnMut(Val)) {
315315
HeapObj::Coroutine(_, slots, stack, _, iters, sub_frames, _) => {
316316
for &v in slots { f(v); }
317317
for &v in stack { f(v); }
318-
for fr in iters { match fr {
319-
IterFrame::Seq { items, .. } => for &v in items { f(v); },
320-
IterFrame::Coroutine(v) => f(*v),
321-
IterFrame::UserDefined(v) => f(*v),
322-
IterFrame::Range { .. } => {}
323-
}}
324-
for sf in sub_frames {
325-
for &v in &sf.slots { f(v); }
326-
for &v in &sf.stack_delta { f(v); }
327-
for fr in &sf.iter_delta { match fr {
328-
IterFrame::Seq { items, .. } => for &v in items { f(v); },
329-
IterFrame::Coroutine(v) => f(*v),
330-
IterFrame::UserDefined(v) => f(*v),
331-
IterFrame::Range { .. } => {}
332-
}}
333-
}
318+
for fr in iters { fr.for_each_val(f); }
319+
for sf in sub_frames { sf.for_each_val(f); }
334320
}
335321
HeapObj::Func(_, defaults, captures) => {
336322
for &v in defaults { f(v); }

0 commit comments

Comments
 (0)