From 0ab928063e13191230a0ae676cdf43ac715672b8 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sat, 2 Apr 2022 22:45:10 -0600 Subject: [PATCH] make marker into an iterators, recover post_order_iterator --- src/heap_iter.rs | 36 ++-- src/machine/arithmetic_ops.rs | 2 +- src/machine/gc.rs | 390 ++++++++++------------------------ src/machine/system_calls.rs | 7 +- 4 files changed, 132 insertions(+), 303 deletions(-) diff --git a/src/heap_iter.rs b/src/heap_iter.rs index f1e9ca66..b1ae5169 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -1,4 +1,5 @@ -// pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter}; +#[cfg(test)] +pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter}; use crate::machine::heap::*; use crate::atom_table::*; @@ -223,15 +224,14 @@ impl<'a> Iterator for StackfulPreOrderHeapIter<'a> { } } -/* #[inline(always)] +#[cfg(test)] pub(crate) fn stackless_preorder_iter( heap: &mut Vec, cell: HeapCellValue, ) -> StacklessPreOrderHeapIter { - StacklessPreOrderHeapIter::new(heap, cell) + StacklessPreOrderHeapIter::::new(heap, cell) } -*/ #[inline(always)] pub(crate) fn stackful_preorder_iter( @@ -337,25 +337,25 @@ pub(crate) fn stackful_post_order_iter<'a>( PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, cell)) } -// pub(crate) type RightistPostOrderHeapIter<'a> = -// PostOrderIterator>; + #[cfg(test)] +pub(crate) type RightistPostOrderHeapIter<'a> = + PostOrderIterator>; -/* #[inline] +#[cfg(test)] pub(crate) fn stackless_post_order_iter<'a>( heap: &'a mut Heap, cell: HeapCellValue, ) -> RightistPostOrderHeapIter<'a> { PostOrderIterator::new(stackless_preorder_iter(heap, cell)) } -*/ #[cfg(test)] mod tests { use super::*; use crate::machine::mock_wam::*; - /* + #[test] fn heap_stackless_iter_tests() { let mut wam = MockWAM::new(); @@ -444,7 +444,7 @@ mod tests { ] )); - for _ in 0..200000 { + for _ in 0..200 { // 000 { let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); assert_eq!( @@ -518,6 +518,7 @@ mod tests { unmark_cell_bits!(iter.next().unwrap()), atom_as_cell!(b_atom) ); + assert_eq!( unmark_cell_bits!(iter.next().unwrap()), atom_as_cell!(a_atom) @@ -579,7 +580,7 @@ mod tests { heap_loc_as_cell!(1), ); - assert_eq!(iter.next(), None); + assert!(iter.next().is_none()); } assert_eq!(wam.machine_st.heap[0], pstr_cell); @@ -606,7 +607,7 @@ mod tests { heap_loc_as_cell!(3), ); - assert_eq!(iter.next(), None); + assert!(iter.next().is_none()); } assert_eq!(wam.machine_st.heap[0], pstr_cell); @@ -628,8 +629,8 @@ mod tests { let pstr_offset_cell = pstr_offset_as_cell!(0); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell); - assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell); + assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell); assert_eq!(iter.next(), None); } @@ -1299,7 +1300,7 @@ mod tests { } */ } -*/ + #[test] fn heap_stackful_iter_tests() { let mut wam = MockWAM::new(); @@ -2219,7 +2220,6 @@ mod tests { wam.machine_st.heap.clear(); } -/* #[test] fn heap_stackless_post_order_iter() { let mut wam = MockWAM::new(); @@ -2313,6 +2313,11 @@ mod tests { let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); + assert_eq!( + unmark_cell_bits!(iter.next().unwrap()), + heap_loc_as_cell!(1) + ); + assert_eq!( unmark_cell_bits!(iter.next().unwrap()), heap_loc_as_cell!(0) @@ -2632,5 +2637,4 @@ mod tests { all_cells_unmarked(&wam.machine_st.heap); } -*/ } diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 6de4d340..2c90cc61 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -1098,7 +1098,7 @@ impl MachineState { pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result { let stub_gen = || functor_stub(atom!("is"), 2); - let mut iter = stackful_post_order_iter(&mut self.heap, value); // was stackless! + let mut iter = stackful_post_order_iter(&mut self.heap, value); while let Some(value) = iter.next() { if value.is_forwarded() { diff --git a/src/machine/gc.rs b/src/machine/gc.rs index 8e93cecc..9d6d56b4 100644 --- a/src/machine/gc.rs +++ b/src/machine/gc.rs @@ -7,13 +7,15 @@ use core::marker::PhantomData; pub(crate) trait UnmarkPolicy { fn unmark(heap: &mut [HeapCellValue], current: usize); fn mark(heap: &mut [HeapCellValue], current: usize); - fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> bool + fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> Option where Self: Sized; } +#[cfg(test)] pub(crate) struct IteratorUMP; +#[cfg(test)] impl UnmarkPolicy for IteratorUMP { #[inline(always)] fn unmark(heap: &mut [HeapCellValue], current: usize) { @@ -24,7 +26,7 @@ impl UnmarkPolicy for IteratorUMP { fn mark(_heap: &mut [HeapCellValue], _current: usize) {} #[inline(always)] - fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> bool { + fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> Option { iter.forward_var() } } @@ -41,7 +43,7 @@ impl UnmarkPolicy for MarkerUMP { } #[inline(always)] - fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> bool { + fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter) -> Option { if iter.heap[iter.current + 1].get_forwarding_bit() == Some(true) { return iter.forward_var(); } @@ -55,8 +57,7 @@ impl UnmarkPolicy for MarkerUMP { iter.heap[iter.current].set_value(temp); iter.heap[iter.current].set_forwarding_bit(true); // forward the attr vars list. - - false + None } } @@ -83,7 +84,7 @@ impl<'a, UMP: UnmarkPolicy> Drop for StacklessPreOrderHeapIter<'a, UMP> { } } -impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { +impl<'a> StacklessPreOrderHeapIter<'a, MarkerUMP> { pub(crate) fn new(heap: &'a mut Vec, cell: HeapCellValue) -> Self { let orig_heap_len = heap.len(); let start = orig_heap_len; // + 1; @@ -103,186 +104,39 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { _marker: PhantomData, } } +} - // NEW implementation! - fn forward_var(&mut self) -> bool { - if self.heap[self.next].get_forwarding_bit() == Some(true) { - return self.backward(); - } - - let temp = self.heap[self.next].get_value(); - - self.heap[self.next].set_value(self.current); - self.current = self.next; - self.next = temp; - - false - } - - fn forward(&mut self) { - loop { - if !self.heap[self.current].get_mark_bit() { - self.heap[self.current].set_mark_bit(true); - - match self.heap[self.current].get_tag() { - HeapCellValueTag::AttrVar => { - if UMP::forward_attr_var(self) { return; } - } - HeapCellValueTag::Var => { - if self.forward_var() { return; } - } - HeapCellValueTag::Str => { - if self.heap[self.next + 1].get_forwarding_bit() == Some(true) { - if self.backward() { - return; - } else { - continue; - } - } - - let h = self.next; - let arity = cell_as_atom_cell!(self.heap[h]).get_arity(); - - for cell in &mut self.heap[h + 1 .. h + arity + 1] { - cell.set_forwarding_bit(true); - } - - let mut last_cell_loc = h + arity; - - self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); - self.current = last_cell_loc; - } - HeapCellValueTag::Lis => { - let mut last_cell_loc = self.next + 1; - - if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) { - if self.backward() { - return; - } else { - continue; - } - } - - self.heap[last_cell_loc].set_forwarding_bit(true); - - self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); - self.current = last_cell_loc; - } - HeapCellValueTag::PStrLoc => { - let h = self.next; - let cell = self.heap[h]; - - if self.heap[h+1].get_forwarding_bit() == Some(true) { - if self.backward() { - return; - } else { - continue; - } - } - - if self.heap[h].get_tag() == HeapCellValueTag::PStr { - let mut last_cell_loc = h+1; - self.heap[last_cell_loc].set_forwarding_bit(true); - - self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); - self.current = last_cell_loc; - } else { - debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset); - - self.next = self.heap[h].get_value(); - self.heap[h].set_value(self.current); - self.current = h; - } - } - HeapCellValueTag::PStrOffset => { - let h = self.next; - - // mark the Fixnum offset. - UMP::mark(self.heap, self.current+1); - - if self.heap[h].get_tag() == HeapCellValueTag::PStr { - let mut last_cell_loc = h+1; - - if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) { - if self.backward() { - return; - } else { - continue; - } - } - - self.heap[last_cell_loc].set_forwarding_bit(true); - - self.next = self.heap[last_cell_loc].get_value(); - self.heap[last_cell_loc].set_value(self.current); - self.current = last_cell_loc; - } else { - debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::CStr); - - self.next = self.heap[h].get_value(); - self.heap[h].set_value(self.current); - self.current = h; - } - } - HeapCellValueTag::StackVar => { - /* - let cell = self.heap[self.current]; - self.heap[self.current].set_forwarding_bit(true); - return Some(cell); - */ - } - _ => { - if self.backward() { - return; - } - } - } - } else { - if self.backward() { - return; - } - } - } - } - - fn backward(&mut self) -> bool { - while !self.heap[self.current].get_forwarding_bit().unwrap_or(false) { - let temp = self.heap[self.current].get_value(); - - // UMP::mark(self.heap, self.current); - - self.heap[self.current].set_value(self.next); - self.next = self.current; - self.current = temp; - } +#[cfg(test)] +impl<'a> StacklessPreOrderHeapIter<'a, IteratorUMP> { + pub(crate) fn new(heap: &'a mut Vec, cell: HeapCellValue) -> Self { + let orig_heap_len = heap.len(); + let start = orig_heap_len + 1; - self.heap[self.current].set_forwarding_bit(false); + heap.push(cell); + heap.push(heap_loc_as_cell!(orig_heap_len)); - // UMP::unmark(self.heap, self.current); + heap[start].set_forwarding_bit(true); + let next = heap[start].get_value(); - if self.current == self.start { - return true; + Self { + heap, + orig_heap_len, + start, + current: start, + next, + _marker: PhantomData, } - - self.current -= 1; - - let temp = self.heap[self.current+1].get_value(); - - self.heap[self.current+1].set_value(self.next); - self.next = self.heap[self.current].get_value(); - self.heap[self.current].set_value(temp); - - false } +} - /* +impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { fn backward_and_return(&mut self) -> Option { let current = self.current; if self.backward() { + // set the f and m bits on the heap cell at start + // so we invoke backward() and return None next call. + self.heap[self.current].set_forwarding_bit(true); self.heap[self.current].set_mark_bit(true); } @@ -291,12 +145,6 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { } fn forward_var(&mut self) -> Option { - if self.heap[self.next].get_mark_bit() { - return self.backward_and_return(); - } - - self.heap[self.current].set_forwarding_bit(true); - if self.heap[self.next].get_forwarding_bit() == Some(true) { return self.backward_and_return(); } @@ -312,45 +160,39 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { fn forward(&mut self) -> Option { loop { - if self.heap[self.current].get_forwarding_bit() != Some(true) { + if !self.heap[self.current].get_mark_bit() { + self.heap[self.current].set_mark_bit(true); + match self.heap[self.current].get_tag() { HeapCellValueTag::AttrVar => { if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); } + + if self.heap[self.next].get_mark_bit() { //self.current == self.next { + return Some(attr_var_as_cell!(self.current)); + } } HeapCellValueTag::Var => { if let Some(cell) = self.forward_var() { return Some(cell); } + + if self.heap[self.next].get_mark_bit() { //self.current == self.next { + return Some(heap_loc_as_cell!(self.current)); + } } HeapCellValueTag::Str => { - // forwarded refs should never be - // marked. leave that to the backward phase. - - if self.heap[self.next + 1].get_mark_bit() { + if self.heap[self.next + 1].get_forwarding_bit() == Some(true) { return self.backward_and_return(); } let h = self.next; let cell = self.heap[h]; - self.heap[h].set_forwarding_bit(true); - self.heap[self.current].set_forwarding_bit(true); - let arity = cell_as_atom_cell!(self.heap[h]).get_arity(); for cell in &mut self.heap[h + 1 .. h + arity + 1] { - if !cell.get_forwarding_bit().unwrap_or(false) { - cell.set_mark_bit(true); - } + cell.set_forwarding_bit(true); } - let mut last_cell_loc = h + arity; - - for cell in self.heap[h + 1 .. h + arity + 1].iter_mut().rev() { - if cell.get_forwarding_bit().unwrap_or(false) { - last_cell_loc -= 1; - } else { - break; - } - } + let last_cell_loc = h + arity; self.next = self.heap[last_cell_loc].get_value(); self.heap[last_cell_loc].set_value(self.current); @@ -359,24 +201,13 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { return Some(cell); } HeapCellValueTag::Lis => { - let mut last_cell_loc = self.next + 1; + let last_cell_loc = self.next + 1; - if self.heap[last_cell_loc].get_mark_bit() { + if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) { return self.backward_and_return(); } - if self.heap[last_cell_loc].get_forwarding_bit().unwrap_or(false) { - // if the tail is already in the - // forwarding chain, use the head in its - // place. apply the same principle to - // forwarded refs elsewhere in this - // function. - last_cell_loc -= 1; - } else { - self.heap[last_cell_loc].set_mark_bit(true); - } - - self.heap[self.current].set_forwarding_bit(true); + self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); self.heap[last_cell_loc].set_value(self.current); @@ -388,25 +219,16 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { let h = self.next; let cell = self.heap[h]; - self.heap[self.current].set_forwarding_bit(true); - - if self.heap[h+1].get_mark_bit() { + if self.heap[h+1].get_forwarding_bit() == Some(true) { return self.backward_and_return(); } if self.heap[h].get_tag() == HeapCellValueTag::PStr { - let mut last_cell_loc = h+1; - - if self.heap[last_cell_loc].get_forwarding_bit().unwrap_or(false) { - last_cell_loc -= 1; - } else { - self.heap[last_cell_loc].set_mark_bit(true); - } + let last_cell_loc = h+1; + self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); self.heap[last_cell_loc].set_value(self.current); - self.heap[h].set_forwarding_bit(true); - self.current = last_cell_loc; } else { debug_assert!(self.heap[h].get_tag() == HeapCellValueTag::PStrOffset); @@ -415,7 +237,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { self.heap[h].set_value(self.current); self.current = h; - if self.heap[h].get_forwarding_bit() == Some(true) { + if self.heap[h].get_mark_bit() { continue; } } @@ -424,23 +246,19 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { } HeapCellValueTag::PStrOffset => { let h = self.next; + let cell = self.heap[h]; + // mark the Fixnum offset. UMP::mark(self.heap, self.current+1); - if self.heap[h].get_tag() == HeapCellValueTag::PStr { - let mut last_cell_loc = h+1; - - if self.heap[last_cell_loc].get_mark_bit() { - return self.backward_and_return(); - } + let last_cell_loc = h+1; - if self.heap[last_cell_loc].get_forwarding_bit().unwrap_or(false) { - last_cell_loc -= 1; - } else { - self.heap[last_cell_loc].set_mark_bit(true); - } + if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) { + return self.backward_and_return(); + } - self.heap[self.current].set_forwarding_bit(true); + if self.heap[h].get_tag() == HeapCellValueTag::PStr { + self.heap[last_cell_loc].set_forwarding_bit(true); self.next = self.heap[last_cell_loc].get_value(); self.heap[last_cell_loc].set_value(self.current); @@ -452,23 +270,25 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { self.heap[h].set_value(self.current); self.current = h; } - } - HeapCellValueTag::StackVar => { - let cell = self.heap[self.current]; - self.heap[self.current].set_forwarding_bit(true); + return Some(cell); } - _ => { - if self.heap[self.current].get_mark_bit() { - let current = self.current; - - if self.backward() { - return None; - } + tag @ HeapCellValueTag::Atom => { + let cell = HeapCellValue::build_with(tag, self.next as u64); + let arity = AtomCell::from_bytes(cell.into_bytes()).get_arity(); - return Some(self.heap[current]); + if arity == 0 { + return self.backward_and_return(); + } else if self.backward() { + return None; } - + } + HeapCellValueTag::PStr => { + if self.backward() { + return None; + } + } + _ => { return self.backward_and_return(); } } @@ -481,20 +301,17 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { } fn backward(&mut self) -> bool { - while !self.heap[self.current].get_mark_bit() { + while !self.heap[self.current].get_forwarding_bit().unwrap_or(false) { let temp = self.heap[self.current].get_value(); - UMP::mark(self.heap, self.current); + UMP::unmark(self.heap, self.current); - self.heap[self.current].set_forwarding_bit(false); self.heap[self.current].set_value(self.next); - self.next = self.current; self.current = temp; } self.heap[self.current].set_forwarding_bit(false); - UMP::unmark(self.heap, self.current); if self.current == self.start { @@ -511,10 +328,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> { false } - */ } -/* impl<'a, UMP: UnmarkPolicy> Iterator for StacklessPreOrderHeapIter<'a, UMP> { type Item = HeapCellValue; @@ -523,26 +338,10 @@ impl<'a, UMP: UnmarkPolicy> Iterator for StacklessPreOrderHeapIter<'a, UMP> { self.forward() } } -*/ pub fn mark_cells(heap: &mut Heap, cell: HeapCellValue) { let mut iter = StacklessPreOrderHeapIter::::new(heap, cell); - - let print_ptrs = |iter: &StacklessPreOrderHeapIter::| { - println!("self.current = {}, self.next = {}\n", iter.current, iter.next); - }; - - iter.forward(); - - print_heap_terms(iter.heap.iter(), 0); - print_ptrs(&iter); - - /* - while let Some(_) = iter.forward() { - print_heap_terms(iter.heap.iter(), 0); - print_ptrs(&iter); - } - */ + while let Some(_) = iter.forward() {} } #[cfg(test)] @@ -1336,8 +1135,6 @@ mod tests { // representation of one of the heap terms as in issue #1384. - println!("DELINEATE"); - wam.machine_st.heap.push(list_loc_as_cell!(7)); wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(list_loc_as_cell!(3)); // A = [B|[]]. @@ -1350,7 +1147,10 @@ mod tests { mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); - all_cells_marked_and_unforwarded(&wam.machine_st.heap); + assert!(wam.machine_st.heap[0].get_mark_bit()); + assert!(!wam.machine_st.heap[1].get_mark_bit()); + + all_cells_marked_and_unforwarded(&wam.machine_st.heap[2 ..]); assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(7)); assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(0)); @@ -1361,5 +1161,35 @@ mod tests { assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(2)); assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), empty_list_as_cell!()); assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), heap_loc_as_cell!(3)); + + wam.machine_st.heap.clear(); + + wam.machine_st.heap.push(str_loc_as_cell!(1)); + wam.machine_st.heap.push(atom_as_cell!(atom!("+"), 2)); + wam.machine_st.heap.push(str_loc_as_cell!(4)); + wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2))); + wam.machine_st.heap.push(atom_as_cell!(atom!("-"), 2)); + wam.machine_st.heap.push(str_loc_as_cell!(7)); + wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1))); + wam.machine_st.heap.push(atom_as_cell!(atom!("+"), 2)); + wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3))); + wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(4))); + + mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(1)); + + print_heap_terms(wam.machine_st.heap[1 ..].iter(), 0); + + all_cells_marked_and_unforwarded(&wam.machine_st.heap); + + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), str_loc_as_cell!(1)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(atom!("+"), 2)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), str_loc_as_cell!(4)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(2))); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(atom!("-"), 2)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), str_loc_as_cell!(7)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), fixnum_as_cell!(Fixnum::build_with(1))); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), atom_as_cell!(atom!("+"), 2)); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(3))); + assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), fixnum_as_cell!(Fixnum::build_with(4))); } } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index c8b999f9..383b6347 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -4905,17 +4905,12 @@ impl Machine { let mut seen_set = IndexSet::new(); { - let orig_heap_len = self.machine_st.heap.len(); let mut iter = stackful_preorder_iter(&mut self.machine_st.heap, stored_v); while let Some(addr) = iter.next() { let addr = unmark_cell_bits!(addr); - if addr.is_var() && addr.get_value() < orig_heap_len { - // the length check is so we don't catalog - // temporary variables created by the iterator, - // that will be deleted when the iterator is - // dropped, into seen_set. + if addr.is_var() { seen_set.insert(addr); } } -- 2.54.0