impl<'a, 'b> AddToFreeList<'a, FactInstruction> for CodeGenerator<'b> {
fn add_term_to_free_list(&mut self, r: RegType) {
- self.marker.add_to_free_list(r);
+ self.marker.add_reg_to_free_list(r);
}
fn add_subterm_to_free_list(&mut self, _term: &Term) {}
#[inline(always)]
fn add_subterm_to_free_list(&mut self, term: &Term) {
if let Some(cell) = structure_cell(term) {
- self.marker.add_to_free_list(cell.get());
+ self.marker.add_reg_to_free_list(cell.get());
}
}
}
code.push_back(instr!("neck_cut"));
} else {
let r = self.marker.get_binding(var_num);
- // let r = self.marker.mark_cut_var(var_num, chunk_num);
code.push_back(instr!("cut", r));
}
&QueryTerm::LocalCut(var_num) => {
let code = branch_code_stack.code(code);
let r = self.marker.get_binding(var_num);
- // let r = self.marker.mark_cut_var(var_num, chunk_num);
code.push_back(instr!("cut", r));
if self.marker.in_tail_position {
}
code.push_back(instr!("proceed"));
+ } else {
+ self.marker.free_cut_var(chunk_num, var_num);
}
}
&QueryTerm::Clause(
p
}
- pub fn add_to_free_list(&mut self, r: RegType) {
+ pub(crate) fn add_reg_to_free_list(&mut self, r: RegType) {
if let RegType::Temp(r) = r {
self.in_use.remove(r);
self.temp_free_list.push(r);
self.var_data.records[var_num].running_count += 1;
}
+ fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) {
+ match &self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(..) => {
+ self.perm_free_list.push_back((chunk_num, var_num));
+ }
+ _ => {}
+ }
+ }
+
fn pop_free_perm(&mut self, chunk_num: usize) -> Option<usize> {
- if let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() {
- if chunk_num == perm_chunk_num {
- None
- } else {
+ while let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() {
+ if chunk_num > perm_chunk_num {
self.perm_free_list.pop_front();
match &mut self.var_data.records[var_num].allocation {
- &mut VarAlloc::Perm(p, _) => {
- Some(p)
+ VarAlloc::Perm(p, PermVarAllocation::Pending) if *p > 0 => {
+ return Some(std::mem::replace(p, 0));
+ }
+ _ => {
}
- _ => unreachable!()
}
+ } else {
+ return None;
+ }
+ }
+
+ None
+ }
+
+ pub(crate) fn free_cut_var(&mut self, chunk_num: usize, var_num: usize) {
+ match &mut self.var_data.records[var_num].allocation {
+ VarAlloc::Perm(_, allocation) => {
+ *allocation = PermVarAllocation::Pending;
+ self.add_perm_to_free_list(chunk_num, var_num);
+ }
+ _ => {
}
- } else {
- None
}
}
if record.running_count < record.num_occurrences {
record.running_count += 1;
} else if r.is_perm() {
- self.perm_free_list.push_back((term_loc.chunk_num(), var_num));
+ self.add_perm_to_free_list(term_loc.chunk_num(), var_num);
}
self.in_use.insert(o);