1102 lines
48 KiB
Rust
1102 lines
48 KiB
Rust
use crate::atom_table::*;
|
|
use crate::machine::heap::*;
|
|
use crate::types::*;
|
|
|
|
use core::marker::PhantomData;
|
|
|
|
// TODO: rename to 'unmark_if_iter', 'mark_if_gc'
|
|
pub(crate) trait UnmarkPolicy {
|
|
fn unmark(heap: &mut [HeapCellValue], current: usize) -> bool;
|
|
fn mark(heap: &mut [HeapCellValue], current: usize);
|
|
fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue>
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
pub(crate) struct IteratorUMP;
|
|
|
|
impl UnmarkPolicy for IteratorUMP {
|
|
#[inline(always)]
|
|
fn unmark(heap: &mut [HeapCellValue], current: usize) -> bool {
|
|
heap[current].set_mark_bit(false);
|
|
false
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn mark(_heap: &mut [HeapCellValue], _current: usize) {}
|
|
|
|
#[inline(always)]
|
|
fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue> {
|
|
iter.forward_var()
|
|
}
|
|
}
|
|
|
|
struct MarkerUMP {}
|
|
|
|
impl UnmarkPolicy for MarkerUMP {
|
|
#[inline(always)]
|
|
fn unmark(_heap: &mut [HeapCellValue], _current: usize) -> bool { true }
|
|
|
|
#[inline(always)]
|
|
fn mark(heap: &mut [HeapCellValue], current: usize) {
|
|
heap[current].set_mark_bit(true);
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue> {
|
|
if iter.heap[iter.current + 1].get_mark_bit() {
|
|
return iter.forward_var();
|
|
}
|
|
|
|
let temp = iter.heap[iter.current].get_value();
|
|
|
|
iter.heap[iter.current].set_value(iter.next);
|
|
iter.current += 1;
|
|
|
|
iter.next = iter.heap[iter.current].get_value();
|
|
|
|
iter.heap[iter.current].set_value(temp);
|
|
iter.heap[iter.current].set_mark_bit(true);
|
|
|
|
None
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct StacklessPreOrderHeapIter<'a, UMP: UnmarkPolicy> {
|
|
pub(crate) heap: &'a mut Vec<HeapCellValue>,
|
|
orig_heap_len: usize,
|
|
start: usize,
|
|
current: usize,
|
|
next: usize,
|
|
_marker: PhantomData<UMP>,
|
|
}
|
|
|
|
impl<'a, UMP: UnmarkPolicy> Drop for StacklessPreOrderHeapIter<'a, UMP> {
|
|
fn drop(&mut self) {
|
|
if self.current == self.start {
|
|
self.heap.truncate(self.orig_heap_len);
|
|
return;
|
|
}
|
|
|
|
while !self.backward() {}
|
|
|
|
self.heap.truncate(self.orig_heap_len);
|
|
}
|
|
}
|
|
|
|
impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|
pub(crate) fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
|
|
let orig_heap_len = heap.len();
|
|
let start = orig_heap_len + 1;
|
|
|
|
heap.push(cell);
|
|
heap.push(heap_loc_as_cell!(orig_heap_len));
|
|
|
|
heap[start].set_mark_bit(true);
|
|
let next = heap[start].get_value();
|
|
|
|
Self {
|
|
heap,
|
|
orig_heap_len,
|
|
start,
|
|
current: start,
|
|
next,
|
|
_marker: PhantomData,
|
|
}
|
|
}
|
|
|
|
fn backward_and_return(&mut self) -> Option<HeapCellValue> {
|
|
let current = self.current;
|
|
|
|
if self.backward() {
|
|
self.heap[self.current].set_forwarding_bit(true);
|
|
self.heap[self.current].set_mark_bit(true);
|
|
}
|
|
|
|
Some(self.heap[current])
|
|
}
|
|
|
|
fn forward_var(&mut self) -> Option<HeapCellValue> {
|
|
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();
|
|
}
|
|
|
|
let temp = self.heap[self.next].get_value();
|
|
|
|
self.heap[self.next].set_value(self.current);
|
|
self.current = self.next;
|
|
self.next = temp;
|
|
|
|
None
|
|
}
|
|
|
|
fn forward(&mut self) -> Option<HeapCellValue> {
|
|
loop {
|
|
if self.heap[self.current].get_forwarding_bit() != Some(true) {
|
|
match self.heap[self.current].get_tag() {
|
|
HeapCellValueTag::AttrVar => {
|
|
if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); }
|
|
}
|
|
HeapCellValueTag::Var => {
|
|
if let Some(cell) = self.forward_var() { return Some(cell); }
|
|
}
|
|
HeapCellValueTag::Str => {
|
|
if self.heap[self.next + 1].get_mark_bit() {
|
|
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] {
|
|
cell.set_mark_bit(true);
|
|
}
|
|
|
|
let 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;
|
|
|
|
return Some(cell);
|
|
}
|
|
HeapCellValueTag::Lis => {
|
|
if self.heap[self.next + 1].get_mark_bit() {
|
|
return self.backward_and_return();
|
|
}
|
|
|
|
self.heap[self.current].set_forwarding_bit(true);
|
|
self.heap[self.next+1].set_mark_bit(true);
|
|
|
|
let last_cell_loc = self.next + 1;
|
|
|
|
self.next = self.heap[last_cell_loc].get_value();
|
|
self.heap[last_cell_loc].set_value(self.current);
|
|
self.current = last_cell_loc;
|
|
|
|
return Some(list_loc_as_cell!(last_cell_loc - 1));
|
|
}
|
|
HeapCellValueTag::PStrLoc => {
|
|
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() {
|
|
return self.backward_and_return();
|
|
}
|
|
|
|
if self.heap[h].get_tag() == HeapCellValueTag::PStr {
|
|
self.heap[h+1].set_mark_bit(true);
|
|
|
|
self.next = self.heap[h+1].get_value();
|
|
self.heap[h+1].set_value(self.current);
|
|
self.heap[h].set_forwarding_bit(true);
|
|
|
|
self.current = h+1;
|
|
} 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;
|
|
|
|
if self.heap[h].get_forwarding_bit() == Some(true) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return Some(cell);
|
|
}
|
|
HeapCellValueTag::PStrOffset => {
|
|
let h = self.next;
|
|
|
|
UMP::mark(self.heap, self.current+1);
|
|
|
|
if self.heap[h].get_tag() == HeapCellValueTag::PStr {
|
|
if self.heap[h+1].get_mark_bit() {
|
|
return self.backward_and_return();
|
|
}
|
|
|
|
self.heap[h+1].set_mark_bit(true);
|
|
self.heap[self.current].set_forwarding_bit(true);
|
|
|
|
self.next = self.heap[h+1].get_value();
|
|
self.heap[h+1].set_value(self.current);
|
|
self.current = h+1;
|
|
} 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.heap[self.current].get_mark_bit() {
|
|
let current = self.current;
|
|
|
|
if self.backward() {
|
|
return None;
|
|
}
|
|
|
|
return Some(self.heap[current]);
|
|
}
|
|
|
|
return self.backward_and_return();
|
|
}
|
|
}
|
|
} else {
|
|
if self.backward() {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn backward(&mut self) -> bool {
|
|
while !self.heap[self.current].get_mark_bit() {
|
|
let temp = self.heap[self.current].get_value();
|
|
|
|
UMP::mark(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);
|
|
|
|
let unmark_is_no_op = UMP::unmark(self.heap, self.current);
|
|
|
|
if self.current == self.start {
|
|
return true;
|
|
}
|
|
|
|
if unmark_is_no_op { // if true, the marker is running.
|
|
let cell = self.heap[self.current];
|
|
|
|
// a cyclic root must be handled specially when marking.
|
|
if self.next >= self.orig_heap_len && cell.is_ref() {
|
|
debug_assert!(cell.get_tag() != HeapCellValueTag::PStrOffset);
|
|
|
|
self.heap[self.current].set_mark_bit(false);
|
|
let prev_current = self.heap[self.current].get_value();
|
|
|
|
if !self.heap[prev_current].is_forwarded() {
|
|
return self.backward();
|
|
}
|
|
}
|
|
}
|
|
|
|
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> Iterator for StacklessPreOrderHeapIter<'a, UMP> {
|
|
type Item = HeapCellValue;
|
|
|
|
#[inline]
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
self.forward()
|
|
}
|
|
}
|
|
|
|
pub fn mark_cells(heap: &mut Heap, cell: HeapCellValue) {
|
|
let mut iter = StacklessPreOrderHeapIter::<MarkerUMP>::new(heap, cell);
|
|
while let Some(_) = iter.forward() {}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::machine::mock_wam::*;
|
|
|
|
#[test]
|
|
fn heap_marking_tests() {
|
|
let mut wam = MockWAM::new();
|
|
|
|
let f_atom = atom!("f");
|
|
let a_atom = atom!("a");
|
|
let b_atom = atom!("b");
|
|
|
|
wam.machine_st
|
|
.heap
|
|
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(f_atom, 2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(b_atom));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.extend(functor!(
|
|
f_atom,
|
|
[
|
|
atom(a_atom),
|
|
atom(b_atom),
|
|
atom(a_atom),
|
|
cell(str_loc_as_cell!(0))
|
|
]
|
|
));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(f_atom, 4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(0));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
// make the structure doubly cyclic.
|
|
wam.machine_st.heap[2] = str_loc_as_cell!(0);
|
|
|
|
mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(str_loc_as_cell!(1));
|
|
|
|
wam.machine_st.heap.extend(functor!(
|
|
f_atom,
|
|
[
|
|
atom(a_atom),
|
|
atom(b_atom),
|
|
atom(a_atom),
|
|
cell(str_loc_as_cell!(1))
|
|
]
|
|
));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(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!(f_atom, 4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), str_loc_as_cell!(1));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), heap_loc_as_cell!(0));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// term is: [a, b]
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(atom_as_cell!(a_atom));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(3));
|
|
wam.machine_st.heap.push(atom_as_cell!(b_atom));
|
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), empty_list_as_cell!());
|
|
|
|
wam.machine_st.heap.pop();
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
// now make the list cyclic.
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), heap_loc_as_cell!(0));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
// make the list doubly cyclic.
|
|
wam.machine_st.heap[3] = heap_loc_as_cell!(0);
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// term is: [a, <stream ptr>]
|
|
let stream = Stream::from_static_string("test", &mut wam.machine_st.arena);
|
|
let stream_cell =
|
|
HeapCellValue::from(ConsPtr::build_with(stream.as_ptr(), ConsPtrMaskTag::Cons));
|
|
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(atom_as_cell!(a_atom));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(3));
|
|
wam.machine_st.heap.push(stream_cell);
|
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), stream_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), empty_list_as_cell!());
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// now a cycle of variables.
|
|
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(2));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(3));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), heap_loc_as_cell!(0));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// first a 'dangling' partial string, later modified to be a
|
|
// two-part complete string, then a three-part cyclic string
|
|
// involving an uncompacted list of chars.
|
|
|
|
let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
|
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
|
|
|
|
wam.machine_st.heap.pop();
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
|
|
|
|
let pstr_second_var_cell = put_partial_string(&mut wam.machine_st.heap, "def", &mut wam.machine_st.atom_tbl);
|
|
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), heap_loc_as_cell!(3));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
wam.machine_st.heap.pop();
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(4));
|
|
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(4));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(3));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(2));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(1));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
wam.machine_st.heap.truncate(4);
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
|
|
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
wam.machine_st.heap[3] = pstr_loc_as_cell!(5);
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(5));
|
|
|
|
assert!(wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(wam.machine_st.heap[6].get_mark_bit());
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), pstr_loc_as_cell!(5));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
|
|
wam.machine_st.heap.push(pstr_cell);
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(4));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
|
|
wam.machine_st.heap.push(pstr_second_cell);
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(7));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("irrelevant stuff")));
|
|
wam.machine_st.heap.push(pstr_offset_as_cell!(1));
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(7));
|
|
|
|
assert!(!wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[6].get_mark_bit());
|
|
assert!(wam.machine_st.heap[7].get_mark_bit());
|
|
assert!(wam.machine_st.heap[8].get_mark_bit());
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(5));
|
|
|
|
assert!(!wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[6].get_mark_bit());
|
|
assert!(wam.machine_st.heap[7].get_mark_bit());
|
|
assert!(wam.machine_st.heap[8].get_mark_bit());
|
|
|
|
for cell in &wam.machine_st.heap {
|
|
assert!(cell.get_forwarding_bit() != Some(true));
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(4));
|
|
|
|
assert!(!wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[6].get_mark_bit());
|
|
assert!(wam.machine_st.heap[7].get_mark_bit());
|
|
assert!(wam.machine_st.heap[8].get_mark_bit());
|
|
|
|
for cell in &wam.machine_st.heap {
|
|
assert!(cell.get_forwarding_bit() != Some(true));
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(2));
|
|
|
|
assert!(!wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[6].get_mark_bit());
|
|
assert!(wam.machine_st.heap[7].get_mark_bit());
|
|
assert!(wam.machine_st.heap[8].get_mark_bit());
|
|
|
|
for cell in &wam.machine_st.heap {
|
|
assert!(cell.get_forwarding_bit() != Some(true));
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
mark_cells(&mut wam.machine_st.heap, pstr_loc_as_cell!(1));
|
|
|
|
assert!(!wam.machine_st.heap[0].get_mark_bit());
|
|
assert!(wam.machine_st.heap[1].get_mark_bit());
|
|
assert!(wam.machine_st.heap[2].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[3].get_mark_bit());
|
|
assert!(wam.machine_st.heap[4].get_mark_bit());
|
|
assert!(wam.machine_st.heap[5].get_mark_bit());
|
|
assert!(!wam.machine_st.heap[6].get_mark_bit());
|
|
assert!(wam.machine_st.heap[7].get_mark_bit());
|
|
assert!(wam.machine_st.heap[8].get_mark_bit());
|
|
|
|
for cell in &wam.machine_st.heap {
|
|
assert!(cell.get_forwarding_bit() != Some(true));
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), pstr_second_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(7));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(atom!("irrelevant stuff")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), pstr_offset_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), fixnum_as_cell!(Fixnum::build_with(2)));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// embedded cyclic partial string.
|
|
|
|
wam.machine_st.heap.push(pstr_cell);
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
|
|
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(5));
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
|
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(4));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(3)));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), list_loc_as_cell!(5));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), empty_list_as_cell!());
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(pstr_cell);
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
|
|
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(5));
|
|
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(4));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(4));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_cell);
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), pstr_offset_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), fixnum_as_cell!(Fixnum::build_with(3)));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), list_loc_as_cell!(5));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), pstr_loc_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(4));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// a chain of variables, ending in a self-referential variable.
|
|
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(2));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(3));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(3));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), heap_loc_as_cell!(3));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// print L = [L|L].
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), list_loc_as_cell!(1));
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
// term is [X,f(Y),Z].
|
|
// Z is an attributed variable, but has a variable attributes list.
|
|
wam.machine_st.heap.push(list_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(3)); // 2
|
|
wam.machine_st.heap.push(list_loc_as_cell!(4)); // 3
|
|
wam.machine_st.heap.push(str_loc_as_cell!(6)); // 4
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(8));
|
|
wam.machine_st.heap.push(atom_as_cell!(f_atom, 1)); // 6
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(11)); // 7
|
|
wam.machine_st.heap.push(list_loc_as_cell!(9));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(9));
|
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
|
|
|
wam.machine_st.heap.push(attr_var_as_cell!(11)); // linked from 7.
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(12));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), list_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(6));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), heap_loc_as_cell!(8));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(f_atom, 1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), heap_loc_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), list_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), heap_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[10]), empty_list_as_cell!());
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[11]), attr_var_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[12]), heap_loc_as_cell!(12));
|
|
|
|
// now populate the attributes list.
|
|
let clpz_atom = atom!("clpz");
|
|
let p_atom = atom!("p");
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
cell.set_forwarding_bit(false);
|
|
}
|
|
|
|
wam.machine_st.heap.pop();
|
|
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(13)); // 12
|
|
wam.machine_st.heap.push(list_loc_as_cell!(14)); // 13
|
|
wam.machine_st.heap.push(str_loc_as_cell!(16)); // 14
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(19)); // 15
|
|
wam.machine_st.heap.push(atom_as_cell!(clpz_atom, 2)); // 16
|
|
wam.machine_st.heap.push(atom_as_cell!(a_atom)); // 17
|
|
wam.machine_st.heap.push(atom_as_cell!(b_atom)); // 18
|
|
wam.machine_st.heap.push(list_loc_as_cell!(20)); // 19
|
|
wam.machine_st.heap.push(str_loc_as_cell!(22)); // 20
|
|
wam.machine_st.heap.push(empty_list_as_cell!()); // 21
|
|
wam.machine_st.heap.push(atom_as_cell!(p_atom, 1)); // 22
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(23)); // 23
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), list_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(6));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), heap_loc_as_cell!(8));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(f_atom, 1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), heap_loc_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), list_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), heap_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[10]), empty_list_as_cell!());
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[11]), attr_var_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[12]), heap_loc_as_cell!(13));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[13]), list_loc_as_cell!(14));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[14]), str_loc_as_cell!(16));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[15]), heap_loc_as_cell!(19));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[16]), atom_as_cell!(clpz_atom, 2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[17]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[18]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[19]), list_loc_as_cell!(20));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[20]), str_loc_as_cell!(22));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[21]), empty_list_as_cell!());
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[22]), atom_as_cell!(p_atom, 1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[23]), heap_loc_as_cell!(23));
|
|
|
|
for cell in &mut wam.machine_st.heap {
|
|
cell.set_mark_bit(false);
|
|
cell.set_forwarding_bit(false);
|
|
}
|
|
|
|
// push some unrelated nonsense cells to the heap and check that they
|
|
// are unmarked after the marker has finished at 0.
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(5));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(5));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(5));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&mut wam.machine_st.heap[0..24]);
|
|
|
|
for cell in &wam.machine_st.heap[24..] {
|
|
assert_eq!(cell.get_mark_bit(), false);
|
|
}
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), list_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(3));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), list_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[4]), str_loc_as_cell!(6));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[5]), heap_loc_as_cell!(8));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), atom_as_cell!(f_atom, 1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), heap_loc_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), list_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), heap_loc_as_cell!(9));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[10]), empty_list_as_cell!());
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[11]), attr_var_as_cell!(11));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[12]), heap_loc_as_cell!(13));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[13]), list_loc_as_cell!(14));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[14]), str_loc_as_cell!(16));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[15]), heap_loc_as_cell!(19));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[16]), atom_as_cell!(clpz_atom, 2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[17]), atom_as_cell!(a_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[18]), atom_as_cell!(b_atom));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[19]), list_loc_as_cell!(20));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[20]), str_loc_as_cell!(22));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[21]), empty_list_as_cell!());
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[22]), atom_as_cell!(p_atom, 1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[23]), heap_loc_as_cell!(23));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[24]), heap_loc_as_cell!(5));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[25]), heap_loc_as_cell!(5));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[26]), list_loc_as_cell!(5));
|
|
|
|
wam.machine_st.heap.clear();
|
|
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0)));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
|
|
|
|
assert_eq!(wam.machine_st.heap.len(), 1);
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(str_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("g"), 2));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("y")));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("="), 2));
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("X")));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
|
wam.machine_st.heap.push(list_loc_as_cell!(8));
|
|
wam.machine_st.heap.push(str_loc_as_cell!(4));
|
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
|
|
|
mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(7));
|
|
|
|
assert_eq!(wam.machine_st.heap.len(), 10);
|
|
|
|
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!("g"), 2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[3]), atom_as_cell!(atom!("y")));
|
|
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]), atom_as_cell!(atom!("X")));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[6]), heap_loc_as_cell!(0));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[7]), list_loc_as_cell!(8));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[8]), str_loc_as_cell!(4));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[9]), empty_list_as_cell!());
|
|
|
|
wam.machine_st.heap.clear();
|
|
|
|
wam.machine_st.heap.push(atom_as_cell!(atom!("f"), 2));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
|
wam.machine_st.heap.push(heap_loc_as_cell!(1));
|
|
|
|
mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(0));
|
|
|
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
|
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("f"), 2));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), heap_loc_as_cell!(1));
|
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[2]), heap_loc_as_cell!(1));
|
|
}
|
|
}
|