_ => { 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),
}
_ => 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),
}
-#[cfg(test)]
pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter};
use crate::machine::heap::*;
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;
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);
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);
}
#[inline(always)]
-#[cfg(test)]
pub(crate) fn stackless_preorder_iter(
heap: &mut Vec<HeapCellValue>,
cell: HeapCellValue,
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,
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,
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)
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!(
Self: Sized;
}
-#[cfg(test)]
pub(crate) struct IteratorUMP;
-#[cfg(test)]
impl UnmarkPolicy for IteratorUMP {
#[inline(always)]
fn unmark(heap: &mut [HeapCellValue], current: usize) {
#[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();
}
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();
}
}
-#[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();
}
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();
}
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();
}
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();
}
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();
}
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();
}
}
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);
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")));
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")));
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")));
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")));
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);
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() {
idx
);
assert!(
- cell.get_forwarding_bit() != Some(true),
+ !cell.get_forwarding_bit(),
"cell {:?} at index {} is forwarded",
cell,
idx
);
assert!(
- cell.get_forwarding_bit() != Some(true),
+ !cell.get_forwarding_bit(),
"cell {:?} at index {} is still forwarded",
cell,
idx
#[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,
}
#[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)
#[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 {})
}
#[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
}
#[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]
#[derive(Copy, Clone, Debug)]
pub struct ConsPtr {
ptr: B61,
+ f: bool,
m: bool,
tag: ConsPtrMaskTag,
}
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)
}
#[derive(BitfieldSpecifier, Copy, Clone, Debug)]
#[bits = 6]
pub(crate) enum RefTag {
- HeapCell = 0b0110,
- StackCell = 0b111,
- AttrVar = 0b10011,
+ HeapCell = 0b000111,
+ StackCell = 0b001001,
+ AttrVar = 0b001011,
}
#[bitfield]
}
}
- #[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() {
}
}
- #[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 => {
}
}
- #[inline]
+ #[inline(always)]
pub fn set_mark_bit(&mut self, m: bool) {
match self.get_tag() {
HeapCellValueTag::Cons => {