fn store(&self, value: HeapCellValue) -> HeapCellValue;
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
fn push(&mut self, value: HeapCellValue);
+ fn push_attr_var_queue(&mut self, attr_var_loc: usize);
fn stack(&mut self) -> &mut Stack;
fn threshold(&self) -> usize;
}
if h >= self.old_h {
*self.value_at_scan() = list_loc_as_cell!(h);
self.scan += 1;
-
return;
}
}
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
if !cdr.is_var() {
+ // mark addr + 1 as a list back edge in the cdr of the list
self.trail_list_cell(addr + 1, threshold);
+ self.target[addr + 1].set_mark_bit(true);
+ self.target[addr + 1].set_forwarding_bit(true);
} else {
let car = self
.target
.store(self.target.deref(heap_loc_as_cell!(addr)));
if !car.is_var() {
+ // mark addr as a list back edge in the car of the list
self.trail_list_cell(addr, threshold);
+ self.target[addr].set_mark_bit(true);
}
}
for (threshold, list_loc) in iter {
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
+ self.target.push_attr_var_queue(threshold - 1);
self.copy_attr_var_list(list_loc);
}
}
}
fn copy_var(&mut self, addr: HeapCellValue) {
+ let index = addr.get_value() as usize;
let rd = self.target.deref(addr);
let ra = self.target.store(rd);
if h >= self.old_h {
*self.value_at_scan() = ra;
self.scan += 1;
+ return;
+ }
+ }
+ (HeapCellValueTag::Lis, h) => {
+ if h >= self.old_h && self.target[index].get_mark_bit() {
+ *self.value_at_scan() = heap_loc_as_cell!(
+ if ra.get_forwarding_bit() {
+ h + 1
+ } else {
+ h
+ }
+ );
+ self.scan += 1;
return;
}
}
}
}
- fn unwind_trail(&mut self) {
- for (r, value) in self.trail.drain(0..) {
+ fn unwind_trail(mut self) {
+ for (r, value) in self.trail {
let index = r.get_value() as usize;
match r.get_tag() {
- RefTag::AttrVar | RefTag::HeapCell => self.target[index] = value,
+ RefTag::AttrVar | RefTag::HeapCell => {
+ self.target[index] = value;
+ self.target[index].set_mark_bit(false);
+ self.target[index].set_forwarding_bit(false);
+ }
RefTag::StackCell => self.target.stack()[index] = value,
}
}
self.state.heap.push(hcv);
}
+ #[inline(always)]
+ fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
+ self.state.attr_var_init.attr_var_queue.push(attr_var_loc);
+ }
+
#[inline(always)]
fn store(&self, value: HeapCellValue) -> HeapCellValue {
self.state.store(value)
#[derive(Debug)]
pub(super) struct CopyBallTerm<'a> {
+ attr_var_queue: &'a mut Vec<usize>,
stack: &'a mut Stack,
heap: &'a mut Heap,
heap_boundary: usize,
}
impl<'a> CopyBallTerm<'a> {
- pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
+ pub(super) fn new(
+ attr_var_queue: &'a mut Vec<usize>,
+ stack: &'a mut Stack,
+ heap: &'a mut Heap,
+ stub: &'a mut Heap,
+ ) -> Self {
let hb = heap.len();
CopyBallTerm {
+ attr_var_queue,
stack,
heap,
heap_boundary: hb,
self.stub.push(value);
}
+ #[inline(always)]
+ fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
+ self.attr_var_queue.push(attr_var_loc);
+ }
+
fn store(&self, value: HeapCellValue) -> HeapCellValue {
read_heap_cell!(value,
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar, h) => {
) -> usize {
let threshold = self.lifted_heap.len() - lh_offset;
- let mut copy_ball_term =
- CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.lifted_heap);
+ let mut copy_ball_term = CopyBallTerm::new(
+ &mut self.attr_var_init.attr_var_queue,
+ &mut self.stack,
+ &mut self.heap,
+ &mut self.lifted_heap,
+ );
copy_ball_term.push(list_loc_as_cell!(threshold + 1));
copy_ball_term.push(heap_loc_as_cell!(threshold + 3));
copy_term(
CopyBallTerm::new(
+ &mut self.machine_st.attr_var_init.attr_var_queue,
&mut self.machine_st.stack,
&mut self.machine_st.heap,
&mut ball.stub,