From: Mark Thom Date: Wed, 6 Apr 2022 02:13:17 +0000 (-0600) Subject: add forwarding bit to all heap cells (#1384) X-Git-Tag: v0.9.1~74 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=f3167f6b5f1e092c83acbe92385e801ece3049a4;p=scryer-prolog.git add forwarding bit to all heap cells (#1384) --- diff --git a/src/arena.rs b/src/arena.rs index bf290f6c..e4ec79ff 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -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), } diff --git a/src/heap_iter.rs b/src/heap_iter.rs index b1ae5169..fdbc6254 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -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, 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>; #[inline] -#[cfg(test)] pub(crate) fn stackless_post_order_iter<'a>( heap: &'a mut Heap, cell: HeapCellValue, diff --git a/src/heap_print.rs b/src/heap_print.rs index fa9c2fca..585d8c13 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -833,7 +833,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { fn check_for_seen(&mut self) -> Option { 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, diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 473f6295..d66fc8e0 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -1098,10 +1098,10 @@ impl MachineState { pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result { 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!( diff --git a/src/machine/gc.rs b/src/machine/gc.rs index 9d6d56b4..a56580ad 100644 --- a/src/machine/gc.rs +++ b/src/machine/gc.rs @@ -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) -> Option { - 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, 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, 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 { - 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); diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 51c8782b..0822c9da 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -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() { diff --git a/src/machine/mock_wam.rs b/src/machine/mock_wam.rs index a184d0de..667097cd 100644 --- a/src/machine/mock_wam.rs +++ b/src/machine/mock_wam.rs @@ -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 diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 3db3ca0e..c2890459 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -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 { - 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 } diff --git a/src/types.rs b/src/types.rs index 1d6b4b2f..3b9d31bf 100644 --- a/src/types.rs +++ b/src/types.rs @@ -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 { + #[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 => {