]> Repositorios git - scryer-prolog.git/commitdiff
free local cut variables after cut
authorMark <[email protected]>
Fri, 23 Jun 2023 18:24:34 +0000 (12:24 -0600)
committerMark <[email protected]>
Fri, 23 Jun 2023 20:11:31 +0000 (14:11 -0600)
src/codegen.rs
src/debray_allocator.rs

index dca532cea08ea71ceb3c353f8b72d1de9933ec9a..873454944fa3fdc2ec3acd4e1f163ee663092429 100644 (file)
@@ -332,7 +332,7 @@ trait AddToFreeList<'a, Target: CompilationTarget<'a>> {
 
 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) {}
@@ -345,7 +345,7 @@ impl<'a, 'b> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'b> {
     #[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());
         }
     }
 }
@@ -881,7 +881,6 @@ impl<'b> CodeGenerator<'b> {
                                     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));
                                 }
 
@@ -896,7 +895,6 @@ impl<'b> CodeGenerator<'b> {
                             &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 {
@@ -905,6 +903,8 @@ impl<'b> CodeGenerator<'b> {
                                     }
 
                                     code.push_back(instr!("proceed"));
+                                } else {
+                                    self.marker.free_cut_var(chunk_num, var_num);
                                 }
                             }
                             &QueryTerm::Clause(
index 6ad47cfc2aa65344493683d192df53f9e91cc1ed..6bfbfb5ed07f8b1accb652ab7b073b9629d9ceb9 100644 (file)
@@ -382,7 +382,7 @@ impl DebrayAllocator {
         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);
@@ -406,22 +406,43 @@ impl DebrayAllocator {
         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
         }
     }
 
@@ -704,7 +725,7 @@ impl Allocator for DebrayAllocator {
         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);