@@ -18,6 +18,7 @@ pub trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
|
|||||||
fn store(&self, value: HeapCellValue) -> HeapCellValue;
|
fn store(&self, value: HeapCellValue) -> HeapCellValue;
|
||||||
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
|
fn deref(&self, value: HeapCellValue) -> HeapCellValue;
|
||||||
fn push(&mut self, value: 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 stack(&mut self) -> &mut Stack;
|
||||||
fn threshold(&self) -> usize;
|
fn threshold(&self) -> usize;
|
||||||
}
|
}
|
||||||
@@ -73,7 +74,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
if h >= self.old_h {
|
if h >= self.old_h {
|
||||||
*self.value_at_scan() = list_loc_as_cell!(h);
|
*self.value_at_scan() = list_loc_as_cell!(h);
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,14 +96,19 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
|
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
|
||||||
|
|
||||||
if !cdr.is_var() {
|
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.trail_list_cell(addr + 1, threshold);
|
||||||
|
self.target[addr + 1].set_mark_bit(true);
|
||||||
|
self.target[addr + 1].set_forwarding_bit(true);
|
||||||
} else {
|
} else {
|
||||||
let car = self
|
let car = self
|
||||||
.target
|
.target
|
||||||
.store(self.target.deref(heap_loc_as_cell!(addr)));
|
.store(self.target.deref(heap_loc_as_cell!(addr)));
|
||||||
|
|
||||||
if !car.is_var() {
|
if !car.is_var() {
|
||||||
|
// mark addr as a list back edge in the car of the list
|
||||||
self.trail_list_cell(addr, threshold);
|
self.trail_list_cell(addr, threshold);
|
||||||
|
self.target[addr].set_mark_bit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +183,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
|
|
||||||
for (threshold, list_loc) in iter {
|
for (threshold, list_loc) in iter {
|
||||||
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
|
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);
|
self.copy_attr_var_list(list_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,6 +269,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn copy_var(&mut self, addr: HeapCellValue) {
|
fn copy_var(&mut self, addr: HeapCellValue) {
|
||||||
|
let index = addr.get_value() as usize;
|
||||||
let rd = self.target.deref(addr);
|
let rd = self.target.deref(addr);
|
||||||
let ra = self.target.store(rd);
|
let ra = self.target.store(rd);
|
||||||
|
|
||||||
@@ -271,7 +278,20 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
if h >= self.old_h {
|
if h >= self.old_h {
|
||||||
*self.value_at_scan() = ra;
|
*self.value_at_scan() = ra;
|
||||||
self.scan += 1;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,12 +376,16 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwind_trail(&mut self) {
|
fn unwind_trail(mut self) {
|
||||||
for (r, value) in self.trail.drain(0..) {
|
for (r, value) in self.trail {
|
||||||
let index = r.get_value() as usize;
|
let index = r.get_value() as usize;
|
||||||
|
|
||||||
match r.get_tag() {
|
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,
|
RefTag::StackCell => self.target.stack()[index] = value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,6 +289,11 @@ impl<'a> CopierTarget for CopyTerm<'a> {
|
|||||||
self.state.heap.push(hcv);
|
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)]
|
#[inline(always)]
|
||||||
fn store(&self, value: HeapCellValue) -> HeapCellValue {
|
fn store(&self, value: HeapCellValue) -> HeapCellValue {
|
||||||
self.state.store(value)
|
self.state.store(value)
|
||||||
@@ -307,6 +312,7 @@ impl<'a> CopierTarget for CopyTerm<'a> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct CopyBallTerm<'a> {
|
pub(super) struct CopyBallTerm<'a> {
|
||||||
|
attr_var_queue: &'a mut Vec<usize>,
|
||||||
stack: &'a mut Stack,
|
stack: &'a mut Stack,
|
||||||
heap: &'a mut Heap,
|
heap: &'a mut Heap,
|
||||||
heap_boundary: usize,
|
heap_boundary: usize,
|
||||||
@@ -314,10 +320,16 @@ pub(super) struct CopyBallTerm<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CopyBallTerm<'a> {
|
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();
|
let hb = heap.len();
|
||||||
|
|
||||||
CopyBallTerm {
|
CopyBallTerm {
|
||||||
|
attr_var_queue,
|
||||||
stack,
|
stack,
|
||||||
heap,
|
heap,
|
||||||
heap_boundary: hb,
|
heap_boundary: hb,
|
||||||
@@ -359,6 +371,11 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
self.stub.push(value);
|
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 {
|
fn store(&self, value: HeapCellValue) -> HeapCellValue {
|
||||||
read_heap_cell!(value,
|
read_heap_cell!(value,
|
||||||
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar, h) => {
|
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar, h) => {
|
||||||
|
|||||||
@@ -334,7 +334,12 @@ impl MachineState {
|
|||||||
self.ball.boundary = self.heap.len();
|
self.ball.boundary = self.heap.len();
|
||||||
|
|
||||||
copy_term(
|
copy_term(
|
||||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.ball.stub),
|
CopyBallTerm::new(
|
||||||
|
&mut self.attr_var_init.attr_var_queue,
|
||||||
|
&mut self.stack,
|
||||||
|
&mut self.heap,
|
||||||
|
&mut self.ball.stub,
|
||||||
|
),
|
||||||
addr,
|
addr,
|
||||||
AttrVarPolicy::DeepCopy,
|
AttrVarPolicy::DeepCopy,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -159,6 +159,14 @@ impl<'a> CopierTarget for TermCopyingMockWAM<'a> {
|
|||||||
self.wam.machine_st.heap.push(val);
|
self.wam.machine_st.heap.push(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_attr_var_queue(&mut self, attr_var_loc: usize) {
|
||||||
|
self.wam
|
||||||
|
.machine_st
|
||||||
|
.attr_var_init
|
||||||
|
.attr_var_queue
|
||||||
|
.push(attr_var_loc);
|
||||||
|
}
|
||||||
|
|
||||||
fn stack(&mut self) -> &mut Stack {
|
fn stack(&mut self) -> &mut Stack {
|
||||||
&mut self.wam.machine_st.stack
|
&mut self.wam.machine_st.stack
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -827,8 +827,12 @@ impl MachineState {
|
|||||||
) -> usize {
|
) -> usize {
|
||||||
let threshold = self.lifted_heap.len() - lh_offset;
|
let threshold = self.lifted_heap.len() - lh_offset;
|
||||||
|
|
||||||
let mut copy_ball_term =
|
let mut copy_ball_term = CopyBallTerm::new(
|
||||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.lifted_heap);
|
&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(list_loc_as_cell!(threshold + 1));
|
||||||
copy_ball_term.push(heap_loc_as_cell!(threshold + 3));
|
copy_ball_term.push(heap_loc_as_cell!(threshold + 3));
|
||||||
@@ -6789,6 +6793,7 @@ impl Machine {
|
|||||||
|
|
||||||
copy_term(
|
copy_term(
|
||||||
CopyBallTerm::new(
|
CopyBallTerm::new(
|
||||||
|
&mut self.machine_st.attr_var_init.attr_var_queue,
|
||||||
&mut self.machine_st.stack,
|
&mut self.machine_st.stack,
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
&mut ball.stub,
|
&mut ball.stub,
|
||||||
|
|||||||
@@ -452,4 +452,4 @@ print_exception_with_check(E) :-
|
|||||||
% is expected to be printed instead.
|
% is expected to be printed instead.
|
||||||
; print_exception(E)
|
; print_exception(E)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user