]> Repositorios git - scryer-prolog.git/commitdiff
add forwarding bit to all heap cells (#1384)
authorMark Thom <[email protected]>
Wed, 6 Apr 2022 02:13:17 +0000 (20:13 -0600)
committerMark Thom <[email protected]>
Wed, 6 Apr 2022 02:34:27 +0000 (20:34 -0600)
src/arena.rs
src/heap_iter.rs
src/heap_print.rs
src/machine/arithmetic_ops.rs
src/machine/gc.rs
src/machine/machine_state_impl.rs
src/machine/mock_wam.rs
src/parser/ast.rs
src/types.rs

index bf290f6c63a9cf321a7c8a4b50ca68ebffd856ec..e4ec79ff85ea15ffe8697c8df88784709494d309 100644 (file)
@@ -808,16 +808,16 @@ mod tests {
             _ => { unreachable!() }
         );
 
-        let fixnum_b_cell = fixnum_as_cell!(Fixnum::build_with(1 << 55));
+        let fixnum_b_cell = fixnum_as_cell!(Fixnum::build_with(1 << 54));
 
         assert_eq!(fixnum_b_cell.get_tag(), HeapCellValueTag::Fixnum);
 
         match fixnum_b_cell.to_fixnum() {
-            Some(n) => assert_eq!(n.get_num(), 1 << 55),
+            Some(n) => assert_eq!(n.get_num(), 1 << 54),
             None => assert!(false),
         }
 
-        match Fixnum::build_with_checked(1 << 57) {
+        match Fixnum::build_with_checked(1 << 56) {
             Ok(_) => assert!(false),
             _ => assert!(true),
         }
@@ -837,17 +837,17 @@ mod tests {
             _ => assert!(false),
         }
 
-        match Fixnum::build_with_checked((1 << 56) - 1) {
-            Ok(n) => assert_eq!(n.get_num(), (1 << 56) - 1),
+        match Fixnum::build_with_checked((1 << 55) - 1) {
+            Ok(n) => assert_eq!(n.get_num(), (1 << 55) - 1),
             _ => assert!(false),
         }
 
-        match Fixnum::build_with_checked(-(1 << 56)) {
-            Ok(n) => assert_eq!(n.get_num(), -(1 << 56)),
+        match Fixnum::build_with_checked(-(1 << 55)) {
+            Ok(n) => assert_eq!(n.get_num(), -(1 << 55)),
             _ => assert!(false),
         }
 
-        match Fixnum::build_with_checked(-(1 << 56) - 1) {
+        match Fixnum::build_with_checked(-(1 << 55) - 1) {
             Ok(_n) => assert!(false),
             _ => assert!(true),
         }
index b1ae51695078d976d6cba158015e7e67a710ee89..fdbc6254f3c736eb5f434793afba0ed87eb46eb5 100644 (file)
@@ -1,4 +1,3 @@
-#[cfg(test)]
 pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter};
 use crate::machine::heap::*;
 
@@ -91,7 +90,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
             let h = h.value() as usize;
             let cell = self.heap[h];
 
-            if cell.get_forwarding_bit() == Some(true) {
+            if cell.get_forwarding_bit() {
                 return Some(h);
             } else if cell.get_mark_bit() && !is_readable_marked {
                 continue;
@@ -122,7 +121,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
 
             let cell = &mut self.heap[h];
 
-            if cell.get_forwarding_bit() == Some(true) {
+            if cell.get_forwarding_bit() {
                 cell.set_forwarding_bit(false);
             } else if cell.get_mark_bit() && !is_readable_marked {
                 cell.set_mark_bit(false);
@@ -150,7 +149,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
             self.h = h;
             let cell = &mut self.heap[h];
 
-            if cell.get_forwarding_bit() == Some(true) {
+            if cell.get_forwarding_bit() {
                 let copy = *cell;
                 cell.set_forwarding_bit(false);
                 return Some(copy);
@@ -225,7 +224,6 @@ impl<'a> Iterator for StackfulPreOrderHeapIter<'a> {
 }
 
 #[inline(always)]
-#[cfg(test)]
 pub(crate) fn stackless_preorder_iter(
     heap: &mut Vec<HeapCellValue>,
     cell: HeapCellValue,
@@ -337,12 +335,10 @@ pub(crate) fn stackful_post_order_iter<'a>(
     PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, cell))
 }
 
-    #[cfg(test)]
 pub(crate) type RightistPostOrderHeapIter<'a> =
     PostOrderIterator<StacklessPreOrderHeapIter<'a, IteratorUMP>>;
 
 #[inline]
-#[cfg(test)]
 pub(crate) fn stackless_post_order_iter<'a>(
     heap: &'a mut Heap,
     cell: HeapCellValue,
index fa9c2fca23ab162115fecfc3cc8ef2ebdb8b9684..585d8c1300e7c7c462e70aad5c191a9bd52e58b6 100644 (file)
@@ -833,7 +833,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
 
     fn check_for_seen(&mut self) -> Option<HeapCellValue> {
         if let Some(addr) = self.iter.next() {
-            let is_cyclic = addr.is_forwarded();
+            let is_cyclic = addr.get_forwarding_bit();
 
             let addr = heap_bound_store(
                 self.iter.heap,
index 473f6295713a19d1959eb50572fe164b624738ae..d66fc8e05e8fc93880532c6bf61e495cb738d8eb 100644 (file)
@@ -1098,10 +1098,10 @@ impl MachineState {
 
     pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result<Number, MachineStub> {
         let stub_gen = || functor_stub(atom!("is"), 2);
-        let mut iter = stackful_post_order_iter(&mut self.heap, value);
+        let mut iter = stackless_post_order_iter(&mut self.heap, value);
 
         while let Some(value) = iter.next() {
-            if value.is_forwarded() {
+            if value.get_forwarding_bit() {
                 let (name, arity) = read_heap_cell!(value,
                      (HeapCellValueTag::Atom, (name, arity)) => {
                          (name, arity)
@@ -1125,8 +1125,8 @@ impl MachineState {
             read_heap_cell!(value,
                 (HeapCellValueTag::Atom, (name, arity)) => {
                     if arity == 2 {
-                        let a2 = self.interms.pop().unwrap();
                         let a1 = self.interms.pop().unwrap();
+                        let a2 = self.interms.pop().unwrap();
 
                         match name {
                             atom!("+") => self.interms.push(drop_iter_on_err!(
index 9d6d56b4ae0f9a2435f6786b409a3f150e40cc05..a56580ad0ec2597a05e4551d1774c3cd47c1bf59 100644 (file)
@@ -12,10 +12,8 @@ pub(crate) trait UnmarkPolicy {
         Self: Sized;
 }
 
-#[cfg(test)]
 pub(crate) struct IteratorUMP;
 
-#[cfg(test)]
 impl UnmarkPolicy for IteratorUMP {
     #[inline(always)]
     fn unmark(heap: &mut [HeapCellValue], current: usize) {
@@ -44,7 +42,7 @@ impl UnmarkPolicy for MarkerUMP {
 
     #[inline(always)]
     fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue> {
-        if iter.heap[iter.current + 1].get_forwarding_bit() == Some(true) {
+        if iter.heap[iter.current + 1].get_forwarding_bit() {
             return iter.forward_var();
         }
 
@@ -87,10 +85,9 @@ impl<'a, UMP: UnmarkPolicy> Drop for StacklessPreOrderHeapIter<'a, UMP> {
 impl<'a> StacklessPreOrderHeapIter<'a, MarkerUMP> {
     pub(crate) fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
         let orig_heap_len = heap.len();
-        let start = orig_heap_len; // + 1;
+        let start = orig_heap_len;
 
         heap.push(cell);
-        // heap.push(heap_loc_as_cell!(orig_heap_len));
 
         heap[start].set_forwarding_bit(true);
         let next = heap[start].get_value();
@@ -106,7 +103,6 @@ impl<'a> StacklessPreOrderHeapIter<'a, MarkerUMP> {
     }
 }
 
-#[cfg(test)]
 impl<'a> StacklessPreOrderHeapIter<'a, IteratorUMP> {
     pub(crate) fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self {
         let orig_heap_len = heap.len();
@@ -145,7 +141,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
     }
 
     fn forward_var(&mut self) -> Option<HeapCellValue> {
-        if self.heap[self.next].get_forwarding_bit() == Some(true) {
+        if self.heap[self.next].get_forwarding_bit() {
             return self.backward_and_return();
         }
 
@@ -167,19 +163,19 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
                     HeapCellValueTag::AttrVar => {
                         if let Some(cell) = UMP::forward_attr_var(self) { return Some(cell); }
 
-                        if self.heap[self.next].get_mark_bit() { //self.current == self.next {
+                        if self.heap[self.next].get_mark_bit() {
                             return Some(attr_var_as_cell!(self.current));
                         }
                     }
                     HeapCellValueTag::Var => {
                         if let Some(cell) = self.forward_var() { return Some(cell); }
 
-                        if self.heap[self.next].get_mark_bit() { //self.current == self.next {
+                        if self.heap[self.next].get_mark_bit() {
                             return Some(heap_loc_as_cell!(self.current));
                         }
                     }
                     HeapCellValueTag::Str => {
-                        if self.heap[self.next + 1].get_forwarding_bit() == Some(true) {
+                        if self.heap[self.next + 1].get_forwarding_bit() {
                             return self.backward_and_return();
                         }
 
@@ -203,7 +199,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
                     HeapCellValueTag::Lis => {
                         let last_cell_loc = self.next + 1;
 
-                        if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) {
+                        if self.heap[last_cell_loc].get_forwarding_bit() {
                             return self.backward_and_return();
                         }
 
@@ -219,7 +215,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
                         let h = self.next;
                         let cell = self.heap[h];
 
-                        if self.heap[h+1].get_forwarding_bit() == Some(true) {
+                        if self.heap[h+1].get_forwarding_bit() {
                             return self.backward_and_return();
                         }
 
@@ -253,7 +249,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
 
                         let last_cell_loc = h+1;
 
-                        if self.heap[last_cell_loc].get_forwarding_bit() == Some(true) {
+                        if self.heap[last_cell_loc].get_forwarding_bit() {
                             return self.backward_and_return();
                         }
 
@@ -301,7 +297,7 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
     }
 
     fn backward(&mut self) -> bool {
-        while !self.heap[self.current].get_forwarding_bit().unwrap_or(false) {
+        while !self.heap[self.current].get_forwarding_bit() {
             let temp = self.heap[self.current].get_value();
 
             UMP::unmark(self.heap, self.current);
@@ -724,7 +720,7 @@ mod tests {
         assert!(wam.machine_st.heap[8].get_mark_bit());
 
         for cell in &wam.machine_st.heap {
-            assert!(cell.get_forwarding_bit() != Some(true));
+            assert!(!cell.get_forwarding_bit());
         }
 
         assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
@@ -754,7 +750,7 @@ mod tests {
         assert!(wam.machine_st.heap[8].get_mark_bit());
 
         for cell in &wam.machine_st.heap {
-            assert!(cell.get_forwarding_bit() != Some(true));
+            assert!(!cell.get_forwarding_bit());
         }
 
         assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
@@ -784,7 +780,7 @@ mod tests {
         assert!(wam.machine_st.heap[8].get_mark_bit());
 
         for cell in &wam.machine_st.heap {
-            assert!(cell.get_forwarding_bit() != Some(true));
+            assert!(!cell.get_forwarding_bit());
         }
 
         assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
@@ -814,7 +810,7 @@ mod tests {
         assert!(wam.machine_st.heap[8].get_mark_bit());
 
         for cell in &wam.machine_st.heap {
-            assert!(cell.get_forwarding_bit() != Some(true));
+            assert!(!cell.get_forwarding_bit());
         }
 
         assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), atom_as_cell!(atom!("irrelevant stuff")));
@@ -1175,9 +1171,7 @@ mod tests {
         wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(3)));
         wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(4)));
 
-        mark_cells(&mut wam.machine_st.heap, str_loc_as_cell!(1));
-
-        print_heap_terms(wam.machine_st.heap[1 ..].iter(), 0);
+        mark_cells(&mut wam.machine_st.heap, heap_loc_as_cell!(0));
 
         all_cells_marked_and_unforwarded(&wam.machine_st.heap);
 
index 51c8782b6909203d7123e09f282d85413951f4e6..0822c9da8834ca50bfa17dfe369efef2685d2897 100644 (file)
@@ -2056,7 +2056,7 @@ impl MachineState {
         let mut iter = stackful_preorder_iter(&mut self.heap, addr);
 
         while let Some(value) = iter.next() {
-            if value.is_forwarded() {
+            if value.get_forwarding_bit() {
                 let value = heap_bound_store(iter.heap, heap_bound_deref(iter.heap, value));
 
                 if value.is_compound() {
index a184d0dec67658fdbf68f0af9834926475c81d20..667097cdb6b2cc08d0b76e7387abbc590ff8a10e 100644 (file)
@@ -168,7 +168,7 @@ pub fn all_cells_marked_and_unforwarded(heap: &[HeapCellValue]) {
             idx
         );
         assert!(
-            cell.get_forwarding_bit() != Some(true),
+            !cell.get_forwarding_bit(),
             "cell {:?} at index {} is forwarded",
             cell,
             idx
@@ -187,7 +187,7 @@ pub fn all_cells_unmarked(heap: &Heap) {
         );
 
         assert!(
-            cell.get_forwarding_bit() != Some(true),
+            !cell.get_forwarding_bit(),
             "cell {:?} at index {} is still forwarded",
             cell,
             idx
index 3db3ca0eb3d81f2d26f5dc2bdaf9f38aa8a5da82..c289045949c73ddb574e48561a568c25e7b39f5a 100644 (file)
@@ -466,7 +466,8 @@ pub enum Fixity {
 #[repr(u64)]
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub struct Fixnum {
-    num: B57,
+    num: B56,
+    #[allow(unused)] f: bool,
     #[allow(unused)] m: bool,
     #[allow(unused)] tag: B6,
 }
@@ -475,7 +476,7 @@ impl Fixnum {
     #[inline]
     pub fn build_with(num: i64) -> Self {
         Fixnum::new()
-            .with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 57) - 1))
+            .with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1))
             .with_tag(HeapCellValueTag::Fixnum as u8)
             .with_m(false)
         //num as u64).with__m(false)
@@ -483,14 +484,14 @@ impl Fixnum {
 
     #[inline]
     pub fn build_with_checked(num: i64) -> Result<Self, OutOfBounds> {
-        const UPPER_BOUND: i64 = (1 << 56) - 1;
-        const LOWER_BOUND: i64 = -(1 << 56);
+        const UPPER_BOUND: i64 = (1 << 55) - 1;
+        const LOWER_BOUND: i64 = -(1 << 55);
 
         if LOWER_BOUND <= num && num <= UPPER_BOUND {
             Ok(Fixnum::new()
                 .with_m(false)
                 .with_tag(HeapCellValueTag::Fixnum as u8)
-                .with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 57) - 1))) //num as u64 & ((1 << 57) - 1)))
+                .with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1)))
         } else {
             Err(OutOfBounds {})
         }
@@ -499,7 +500,7 @@ impl Fixnum {
     #[inline]
     pub fn get_num(self) -> i64 {
         let n = self.num() as i64;
-        let (n, overflowed) = (n << 7).overflowing_shr(7); // sign-extend the 57-bit signed fixnum.
+        let (n, overflowed) = (n << 8).overflowing_shr(8);
         debug_assert_eq!(overflowed, false);
         n
     }
index 1d6b4b2f9905273635d3eda49f60d302bd01fb3a..3b9d31bfe03717cdba1e1a4e8312d3b305cee9bb 100644 (file)
@@ -15,55 +15,55 @@ use std::ops::{Add, Sub, SubAssign};
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[bits = 6]
 pub enum HeapCellValueTag {
-    Str = 0b000010,
-    Lis = 0b000011,
-    Var = 0b000110,
-    StackVar = 0b000111,
-    AttrVar = 0b010011,
-    PStrLoc = 0b111111,
-    PStrOffset = 0b001110,
+    Str = 0b000011,
+    Lis = 0b000101,
+    Var = 0b000111,
+    StackVar = 0b001001,
+    AttrVar = 0b001011,
+    PStrLoc = 0b001101,
+    PStrOffset = 0b001111,
     // constants.
     Cons = 0b0,
-    F64  = 0b000001,
-    Fixnum = 0b010010,
-    Char = 0b011011,
-    Atom = 0b001010,
-    PStr = 0b001011,
-    CStr = 0b010110, // a complete string.
+    F64  = 0b010001,
+    Fixnum = 0b010011,
+    Char = 0b010101,
+    Atom = 0b010111,
+    PStr = 0b011001,
+    CStr = 0b011011,
 }
 
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[bits = 6]
 pub enum HeapCellValueView {
-    Str = 0b000010,
-    Lis = 0b000011,
-    Var = 0b000110,
-    StackVar = 0b000111,
-    AttrVar = 0b010011,
-    PStrLoc = 0b111111,
-    PStrOffset = 0b001110,
+    Str = 0b000011,
+    Lis = 0b000101,
+    Var = 0b000111,
+    StackVar = 0b001001,
+    AttrVar = 0b001011,
+    PStrLoc = 0b001101,
+    PStrOffset = 0b001111,
     // constants.
-    Cons = 0b00,
-    F64  = 0b000001,
-    Fixnum = 0b010010,
-    Char = 0b011011,
-    Atom = 0b001010,
-    PStr = 0b001011,
-    CStr = 0b010110,
+    Cons = 0b0,
+    F64  = 0b010001,
+    Fixnum = 0b010011,
+    Char = 0b010101,
+    Atom = 0b010111,
+    PStr = 0b011001,
+    CStr = 0b011011,
     // trail elements.
-    TrailedHeapVar = 0b011110,
+    TrailedHeapVar = 0b011101,
     TrailedStackVar = 0b011111,
-    TrailedAttrVarHeapLink = 0b101110,
-    TrailedAttrVarListLink = 0b100010,
-    TrailedAttachedValue = 0b101010,
-    TrailedBlackboardEntry = 0b100110,
-    TrailedBlackboardOffset = 0b100111,
+    TrailedAttrVarHeapLink =  0b100001,
+    TrailedAttrVarListLink =  0b100011,
+    TrailedAttachedValue =    0b100101,
+    TrailedBlackboardEntry =  0b100111,
+    TrailedBlackboardOffset = 0b101001,
 }
 
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-#[bits = 2]
+#[bits = 1]
 pub enum ConsPtrMaskTag {
-    Cons = 0b00,
+    Cons = 0b0,
 }
 
 #[bitfield]
@@ -71,6 +71,7 @@ pub enum ConsPtrMaskTag {
 #[derive(Copy, Clone, Debug)]
 pub struct ConsPtr {
     ptr: B61,
+    f: bool,
     m: bool,
     tag: ConsPtrMaskTag,
 }
@@ -80,6 +81,7 @@ impl ConsPtr {
     pub fn build_with(ptr: *const ArenaHeader, tag: ConsPtrMaskTag) -> Self {
         ConsPtr::new()
             .with_ptr(ptr as *const u8 as u64)
+            .with_f(false)
             .with_m(false)
             .with_tag(tag)
     }
@@ -98,9 +100,9 @@ impl ConsPtr {
 #[derive(BitfieldSpecifier, Copy, Clone, Debug)]
 #[bits = 6]
 pub(crate) enum RefTag {
-    HeapCell = 0b0110,
-    StackCell = 0b111,
-    AttrVar = 0b10011,
+    HeapCell = 0b000111,
+    StackCell = 0b001001,
+    AttrVar = 0b001011,
 }
 
 #[bitfield]
@@ -379,11 +381,6 @@ impl HeapCellValue {
         }
     }
 
-    #[inline(always)]
-    pub fn is_forwarded(self) -> bool {
-        self.get_forwarding_bit().unwrap_or(false)
-    }
-
     #[inline]
     pub fn is_ref(self) -> bool {
         match self.get_tag() {
@@ -536,33 +533,26 @@ impl HeapCellValue {
         }
     }
 
-    #[inline]
-    pub fn get_forwarding_bit(self) -> Option<bool> {
+    #[inline(always)]
+    pub fn get_forwarding_bit(self) -> bool {
         match self.get_tag() {
-            HeapCellValueTag::Cons        // the list of non-forwardable cell tags.
-                | HeapCellValueTag::F64
-                // | HeapCellValueTag::Atom
-                // | HeapCellValueTag::PStr
-                | HeapCellValueTag::Fixnum
-                | HeapCellValueTag::Char => None,
-            _ => Some(self.f()),
+            HeapCellValueTag::Cons => ConsPtr::from_bytes(self.into_bytes()).f(),
+            _ => self.f()
         }
     }
 
-    #[inline]
+    #[inline(always)]
     pub fn set_forwarding_bit(&mut self, f: bool) {
         match self.get_tag() {
-            HeapCellValueTag::Cons        // the list of non-forwardable cell tags.
-                | HeapCellValueTag::F64
-                // | HeapCellValueTag::Atom
-                // | HeapCellValueTag::PStr
-                | HeapCellValueTag::Fixnum
-                | HeapCellValueTag::Char => {}
+            HeapCellValueTag::Cons => {
+                let value = ConsPtr::from_bytes(self.into_bytes()).with_f(f);
+                *self = HeapCellValue::from_bytes(value.into_bytes());
+            }
             _ => self.set_f(f),
         }
     }
 
-    #[inline]
+    #[inline(always)]
     pub fn get_mark_bit(self) -> bool {
         match self.get_tag() {
             HeapCellValueTag::Cons => {
@@ -572,7 +562,7 @@ impl HeapCellValue {
         }
     }
 
-    #[inline]
+    #[inline(always)]
     pub fn set_mark_bit(&mut self, m: bool) {
         match self.get_tag() {
             HeapCellValueTag::Cons => {