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