]> Repositorios git - scryer-prolog.git/commitdiff
allocate floats in dedicated buffer
authorMark Thom <[email protected]>
Tue, 5 Apr 2022 05:56:30 +0000 (23:56 -0600)
committerMark Thom <[email protected]>
Wed, 6 Apr 2022 02:34:27 +0000 (20:34 -0600)
14 files changed:
src/arena.rs
src/arithmetic.rs
src/forms.rs
src/heap_print.rs
src/machine/arithmetic_ops.rs
src/machine/dispatch.rs
src/machine/heap.rs
src/machine/machine_state_impl.rs
src/machine/mock_wam.rs
src/machine/system_calls.rs
src/macros.rs
src/parser/lexer.rs
src/parser/parser.rs
src/types.rs

index f7490b66c8b9e794fadc46197fd7114ac3451b02..bf290f6c63a9cf321a7c8a4b50ca68ebffd856ec 100644 (file)
@@ -1,6 +1,7 @@
 use crate::machine::loader::LiveLoadState;
 use crate::machine::machine_indices::*;
 use crate::machine::streams::*;
+use crate::raw_block::*;
 use crate::read::*;
 
 use modular_bitfield::prelude::*;
@@ -24,10 +25,110 @@ macro_rules! arena_alloc {
     }};
 }
 
+#[macro_export]
+macro_rules! float_alloc {
+    ($e:expr, $arena:expr) => {{
+        let result = $e;
+        #[allow(unused_unsafe)]
+        unsafe { $arena.f64_tbl.build_with(result) }
+    }};
+}
+
+#[cfg(test)]
+use std::cell::RefCell;
+
+const F64_TABLE_INIT_SIZE: usize = 1 << 16;
+const F64_TABLE_ALIGN: usize = 8;
+
+#[cfg(test)]
+thread_local! {
+    static F64_TABLE_BUF_BASE: RefCell<*const u8> = RefCell::new(ptr::null_mut());
+}
+
+#[cfg(not(test))]
+static mut F64_TABLE_BUF_BASE: *const u8 = ptr::null_mut();
+
+impl RawBlockTraits for F64Table {
+    #[inline]
+    fn init_size() -> usize {
+        F64_TABLE_INIT_SIZE
+    }
+
+    #[inline]
+    fn align() -> usize {
+        F64_TABLE_ALIGN
+    }
+}
+
+#[derive(Debug)]
+pub struct F64Table {
+    block: RawBlock<F64Table>,
+}
+
+impl Drop for F64Table {
+    fn drop(&mut self) {
+        self.block.deallocate();
+    }
+}
+
+#[cfg(test)]
+fn set_f64_tbl_buf_base(ptr: *const u8) {
+    F64_TABLE_BUF_BASE.with(|f64_table_buf_base| {
+        *f64_table_buf_base.borrow_mut() = ptr;
+    });
+}
+
+#[cfg(test)]
+pub(crate) fn get_f64_tbl_buf_base() -> *const u8 {
+    F64_TABLE_BUF_BASE.with(|f64_table_buf_base| *f64_table_buf_base.borrow())
+}
+
+#[cfg(not(test))]
+fn set_f64_tbl_buf_base(ptr: *const u8) {
+    unsafe {
+        F64_TABLE_BUF_BASE = ptr;
+    }
+}
+
+#[cfg(not(test))]
+pub(crate) fn get_f64_tbl_buf_base() -> *const u8 {
+    unsafe { F64_TABLE_BUF_BASE }
+}
+
+#[inline(always)]
+pub fn lookup_float(offset: usize) -> *mut OrderedFloat<f64> {
+    let base = get_f64_tbl_buf_base() as usize;
+    (base + offset) as *mut _
+}
+
+impl F64Table {
+    #[inline]
+    pub fn new() -> Self {
+        F64Table { block: RawBlock::new() }
+    }
+
+    pub unsafe fn build_with(&mut self, value: f64) -> F64Ptr {
+        let mut ptr;
+
+        loop {
+            ptr = self.block.alloc(mem::size_of::<f64>());
+
+            if ptr.is_null() {
+                self.block.grow();
+                set_f64_tbl_buf_base(self.block.base);
+            } else {
+                break;
+            }
+        }
+
+        ptr::write(ptr as *mut f64, value);
+        F64Ptr(ptr::NonNull::new_unchecked(ptr as *mut _))
+    }
+}
+
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq)]
 #[bits = 7]
 pub enum ArenaHeaderTag {
-    F64 = 0b01,
     Integer = 0b10,
     Rational = 0b11,
     OssifiedOpDir = 0b0000100,
@@ -197,7 +298,7 @@ pub trait ArenaAllocated {
 }
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct F64Ptr(pub TypedArenaPtr<OrderedFloat<f64>>);
+pub struct F64Ptr(pub ptr::NonNull<OrderedFloat<f64>>);
 
 impl fmt::Display for F64Ptr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -206,41 +307,33 @@ impl fmt::Display for F64Ptr {
 }
 
 impl Deref for F64Ptr {
-    type Target = TypedArenaPtr<OrderedFloat<f64>>;
+    type Target = OrderedFloat<f64>;
 
     #[inline]
     fn deref(&self) -> &Self::Target {
-        &self.0
+        unsafe { &*self.0.as_ptr() }
     }
 }
 
 impl DerefMut for F64Ptr {
     #[inline]
     fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
+        unsafe { &mut *self.0.as_ptr() }
     }
 }
 
-impl ArenaAllocated for OrderedFloat<f64> {
-    type PtrToAllocated = F64Ptr;
-
-    #[inline]
-    fn tag() -> ArenaHeaderTag {
-        ArenaHeaderTag::F64
-    }
-
-    #[inline]
-    fn size(&self) -> usize {
-        mem::size_of::<Self>()
-    }
-
-    #[inline]
-    fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
+impl F64Ptr {
+    #[inline(always)]
+    pub fn from_offset(offset: usize) -> Self {
         unsafe {
-            ptr::write(dst, self);
-            F64Ptr(TypedArenaPtr::new(dst as *mut Self))
+            F64Ptr(ptr::NonNull::new_unchecked(lookup_float(offset)))
         }
     }
+
+    #[inline(always)]
+    pub fn as_offset(&self) -> usize {
+        self.0.as_ptr() as usize - get_f64_tbl_buf_base() as usize
+    }
 }
 
 impl ArenaAllocated for Integer {
@@ -360,7 +453,10 @@ struct AllocSlab {
 }
 
 #[derive(Debug)]
-pub struct Arena(*mut AllocSlab);
+pub struct Arena {
+    base: *mut AllocSlab,
+    pub f64_tbl: F64Table,
+}
 
 unsafe impl Send for Arena {}
 unsafe impl Sync for Arena {}
@@ -368,7 +464,7 @@ unsafe impl Sync for Arena {}
 impl Arena {
     #[inline]
     pub fn new() -> Self {
-        Arena(ptr::null_mut())
+        Arena { base: ptr::null_mut(), f64_tbl: F64Table::new() }
     }
 
     pub unsafe fn alloc<T: ArenaAllocated>(&mut self, value: T) -> T::PtrToAllocated {
@@ -379,13 +475,13 @@ impl Arena {
 
         let slab = alloc::alloc(layout) as *mut AllocSlab;
 
-        (*slab).next = self.0;
+        (*slab).next = self.base;
         (*slab).header = ArenaHeader::build_with(value.size() as u64, T::tag());
 
         let offset = (*slab).payload_offset();
         let result = value.copy_to_arena(offset as *mut T);
 
-        self.0 = slab;
+        self.base = slab;
 
         result
     }
@@ -442,14 +538,14 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
         ArenaHeaderTag::StandardErrorStream => {
             ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardErrorStream>>());
         }
-        ArenaHeaderTag::F64 | ArenaHeaderTag::NullStream => {
+        ArenaHeaderTag::NullStream => {
         }
     }
 }
 
 impl Drop for Arena {
     fn drop(&mut self) {
-        let mut ptr = self.0;
+        let mut ptr = self.base;
 
         while !ptr.is_null() {
             unsafe {
@@ -468,7 +564,7 @@ impl Drop for Arena {
             }
         }
 
-        self.0 = ptr::null_mut();
+        self.base = ptr::null_mut();
     }
 }
 
@@ -501,21 +597,21 @@ mod tests {
     fn float_ptr_cast() {
         let mut wam = MockWAM::new();
 
-        let f = OrderedFloat(0f64);
-        let mut fp = arena_alloc!(f, &mut wam.machine_st.arena);
-        let cell = HeapCellValue::from(fp);
+        let f = 0f64;
+        let fp = float_alloc!(f, wam.machine_st.arena);
+        let mut cell = HeapCellValue::from(fp);
 
         assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
-        assert_eq!(fp.get_mark_bit(), false);
-        assert_eq!(**fp, f);
+        assert_eq!(cell.get_mark_bit(), false);
+        assert_eq!(*fp, OrderedFloat(f));
 
-        fp.mark();
+        cell.set_mark_bit(true);
 
-        assert_eq!(fp.get_mark_bit(), true);
+        assert_eq!(cell.get_mark_bit(), true);
 
         read_heap_cell!(cell,
             (HeapCellValueTag::F64, ptr) => {
-                assert_eq!(**ptr, f)
+                assert_eq!(OrderedFloat(*ptr), OrderedFloat(f))
             }
             _ => { unreachable!() }
         );
@@ -558,8 +654,8 @@ mod tests {
 
         // integer
 
-        let big_int = 2 * Integer::from(1u64 << 63);
-        let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, &mut wam.machine_st.arena);
+        let big_int: Integer = 2 * Integer::from(1u64 << 63);
+        let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, wam.machine_st.arena);
 
         assert!(!big_int_ptr.as_ptr().is_null());
 
@@ -763,22 +859,11 @@ mod tests {
 
         // float
 
-        let float = OrderedFloat(3.1415926f64);
-        let float_ptr = arena_alloc!(float, &mut wam.machine_st.arena);
+        let float = 3.1415926f64;
+        let float_ptr = float_alloc!(float, wam.machine_st.arena);
+        let cell = HeapCellValue::from(float_ptr);
 
-        assert!(!float_ptr.as_ptr().is_null());
-
-        let float_cell = typed_arena_ptr_as_cell!(float_ptr);
-        assert_eq!(cell.get_tag(), HeapCellValueTag::Cons);
-
-        match float_cell.to_untyped_arena_ptr() {
-            Some(untyped_arena_ptr) => {
-                assert_eq!(Some(float_ptr.header_ptr()), Some(untyped_arena_ptr.into()),);
-            }
-            None => {
-                assert!(false); // we fail.
-            }
-        }
+        assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
 
         // char
 
index cc0b01942460641606c775bc0de522f9e9aab1db..d4fa8e380daca392a48ba76cfc23a32178af9c64 100644 (file)
@@ -169,16 +169,16 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
     match c {
         Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
         Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*n))),
-        Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(***n))),
+        Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(**n))),
         Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
         Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
-            Number::Float(OrderedFloat(f64::consts::E)),
+            Number::Float(OrderedFloat(std::f64::consts::E))
         )),
         Literal::Atom(name) if name == &atom!("pi") => interm.push(ArithmeticTerm::Number(
-            Number::Float(OrderedFloat(f64::consts::PI)),
+            Number::Float(OrderedFloat(std::f64::consts::PI))
         )),
         Literal::Atom(name) if name == &atom!("epsilon") => interm.push(ArithmeticTerm::Number(
-            Number::Float(OrderedFloat(f64::EPSILON)),
+            Number::Float(OrderedFloat(std::f64::EPSILON))
         )),
         _ => return Err(ArithmeticError::NonEvaluableFunctor(*c, 0)),
     }
@@ -375,16 +375,16 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
 pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
     match n {
         &Number::Integer(_) | &Number::Fixnum(_) => *n,
-        &Number::Float(OrderedFloat(f)) => {
+        &Number::Float(f) => {
             let f = f.floor();
 
             const I64_MIN_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64);
             const I64_MAX_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64);
 
-            if I64_MIN_TO_F <= OrderedFloat(f) && OrderedFloat(f) <= I64_MAX_TO_F {
-                fixnum!(Number, f as i64, arena)
+            if I64_MIN_TO_F <= f && f <= I64_MAX_TO_F {
+                fixnum!(Number, f.into_inner() as i64, arena)
             } else {
-                Number::Integer(arena_alloc!(Integer::from_f64(f).unwrap(), arena))
+                Number::Integer(arena_alloc!(Integer::from_f64(f.into_inner()).unwrap(), arena))
             }
         }
         &Number::Rational(ref r) => {
@@ -415,23 +415,14 @@ pub(crate) fn rnd_f(n: &Number) -> f64 {
 }
 
 // floating point result function -- 9.1.4.2.
-pub(crate) fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError>
-where
-    Round: Fn(&Number) -> f64,
-{
-    let f = rnd_f(n);
-    classify_float(f, round)
+pub(crate) fn result_f(n: &Number) -> Result<f64, EvalError> {
+    classify_float(rnd_f(n))
 }
 
-fn classify_float<Round>(f: f64, round: Round) -> Result<f64, EvalError>
-where
-    Round: Fn(&Number) -> f64,
-{
+fn classify_float(f: f64) -> Result<f64, EvalError> {
     match f.classify() {
-        FpCategory::Normal | FpCategory::Zero => Ok(round(&Number::Float(OrderedFloat(f)))),
+        FpCategory::Normal | FpCategory::Zero => Ok(f),
         FpCategory::Infinite => {
-            let f = round(&Number::Float(OrderedFloat(f)));
-
             if OrderedFloat(f) == OrderedFloat(f64::MAX) {
                 Ok(f)
             } else {
@@ -439,33 +430,33 @@ where
             }
         }
         FpCategory::Nan => Err(EvalError::Undefined),
-        _ => Ok(round(&Number::Float(OrderedFloat(f)))),
+        _ => Ok(f)
     }
 }
 
 #[inline]
 pub(crate) fn float_fn_to_f(n: i64) -> Result<f64, EvalError> {
-    classify_float(n as f64, rnd_f)
+    classify_float(n as f64)
 }
 
 #[inline]
 pub(crate) fn float_i_to_f(n: &Integer) -> Result<f64, EvalError> {
-    classify_float(n.to_f64(), rnd_f)
+    classify_float(n.to_f64())
 }
 
 #[inline]
 pub(crate) fn float_r_to_f(r: &Rational) -> Result<f64, EvalError> {
-    classify_float(r.to_f64(), rnd_f)
+    classify_float(r.to_f64())
 }
 
 #[inline]
 pub(crate) fn add_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
-    Ok(OrderedFloat(classify_float(f1 + f2, rnd_f)?))
+    Ok(OrderedFloat(classify_float(f1 + f2)?))
 }
 
 #[inline]
 pub(crate) fn mul_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
-    Ok(OrderedFloat(classify_float(f1 * f2, rnd_f)?))
+    Ok(OrderedFloat(classify_float(f1 * f2)?))
 }
 
 #[inline]
@@ -473,7 +464,7 @@ fn div_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
     if FpCategory::Zero == f2.classify() {
         Err(EvalError::ZeroDivisor)
     } else {
-        Ok(OrderedFloat(classify_float(f1 / f2, rnd_f)?))
+        Ok(OrderedFloat(classify_float(f1 / f2)?))
     }
 }
 
@@ -683,9 +674,6 @@ impl TryFrom<HeapCellValue> for Number {
         read_heap_cell!(value,
            (HeapCellValueTag::Cons, c) => {
                match_untyped_arena_ptr!(c,
-                  (ArenaHeaderTag::F64, n) => {
-                      Ok(Number::Float(*n))
-                  }
                   (ArenaHeaderTag::Integer, n) => {
                       Ok(Number::Integer(n))
                   }
@@ -698,7 +686,7 @@ impl TryFrom<HeapCellValue> for Number {
                )
            }
            (HeapCellValueTag::F64, n) => {
-               Ok(Number::Float(**n))
+               Ok(Number::Float(*n))
            }
            (HeapCellValueTag::Fixnum, n) => {
                Ok(Number::Fixnum(n))
index 1b61546a1da59d9fadee6d10b54f2221b8843104..f1c634bc16c090f1c5cf209dc52f6a67c855c73b 100644 (file)
@@ -608,7 +608,7 @@ impl ArenaFrom<Number> for Literal {
         match value {
             Number::Fixnum(n) => Literal::Fixnum(n),
             Number::Integer(n) => Literal::Integer(n),
-            Number::Float(f) => Literal::Float(arena_alloc!(f, arena)),
+            Number::Float(OrderedFloat(f)) => Literal::Float(float_alloc!(f, arena)),
             Number::Rational(r) => Literal::Rational(r),
         }
     }
@@ -620,7 +620,7 @@ impl ArenaFrom<Number> for HeapCellValue {
         match value {
             Number::Fixnum(n) => fixnum_as_cell!(n),
             Number::Integer(n) => typed_arena_ptr_as_cell!(n),
-            Number::Float(n) => typed_arena_ptr_as_cell!(arena_alloc!(n, arena)),
+            Number::Float(OrderedFloat(n)) => HeapCellValue::from(float_alloc!(n, arena)),
             Number::Rational(n) => typed_arena_ptr_as_cell!(n),
         }
     }
index 86db4bee71d7a8296bcb26359555c6a6fef9ebd5..fa9c2fca23ab162115fecfc3cc8ef2ebdb8b9684 100644 (file)
@@ -1486,7 +1486,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 self.print_number(max_depth, NumberFocus::Unfocused(Number::Fixnum(n)), &op);
             }
             (HeapCellValueTag::F64, f) => {
-                self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(**f)), &op);
+                self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(*f)), &op);
             }
             (HeapCellValueTag::CStr | HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => {
                 self.print_list_like(max_depth);
@@ -1513,9 +1513,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             }
             (HeapCellValueTag::Cons, c) => {
                 match_untyped_arena_ptr!(c,
-                    (ArenaHeaderTag::F64, f) => {
-                        self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(*f)), &op);
-                    }
                     (ArenaHeaderTag::Integer, n) => {
                         self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op);
                     }
index 2c90cc61f398cb4b88d071d98135da67ba4a4659..473f6295713a19d1959eb50572fe164b624738ae 100644 (file)
@@ -281,8 +281,8 @@ pub(crate) fn div(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
 }
 
 pub(crate) fn float_pow(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
-    let f1 = result_f(&n1, rnd_f);
-    let f2 = result_f(&n2, rnd_f);
+    let f1 = result_f(&n1);
+    let f2 = result_f(&n2);
 
     let stub_gen = || {
         let pow_atom = atom!("**");
@@ -292,7 +292,7 @@ pub(crate) fn float_pow(n1: Number, n2: Number) -> Result<Number, MachineStubGen
     let f1 = try_numeric_result!(f1, stub_gen)?;
     let f2 = try_numeric_result!(f2, stub_gen)?;
 
-    let result = result_f(&Number::Float(OrderedFloat(f1.powf(f2))), rnd_f);
+    let result = result_f(&Number::Float(OrderedFloat(f1.powf(f2))));
 
     Ok(Number::Float(OrderedFloat(try_numeric_result!(
         result, stub_gen
@@ -404,7 +404,7 @@ pub(crate) fn float(n: Number) -> Result<f64, MachineStubGen> {
         functor_stub(is_atom, 2)
     };
 
-    try_numeric_result!(result_f(&n, rnd_f), stub_gen)
+    try_numeric_result!(result_f(&n), stub_gen)
 }
 
 #[inline]
@@ -420,8 +420,8 @@ where
         functor_stub(is_atom, 2)
     };
 
-    let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?;
-    let f1 = result_f(&Number::Float(OrderedFloat(f(f1))), rnd_f);
+    let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
+    let f1 = result_f(&Number::Float(OrderedFloat(f(f1))));
 
     try_numeric_result!(f1, stub_gen)
 }
@@ -462,8 +462,8 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
                 functor_stub(max_atom, 2)
             };
 
-            let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?;
-            let f2 = try_numeric_result!(result_f(&n2, rnd_f), stub_gen)?;
+            let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
+            let f2 = try_numeric_result!(result_f(&n2), stub_gen)?;
 
             Ok(Number::Float(cmp::max(OrderedFloat(f1), OrderedFloat(f2))))
         }
@@ -506,8 +506,8 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
                 functor_stub(min_atom, 2)
             };
 
-            let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?;
-            let f2 = try_numeric_result!(result_f(&n2, rnd_f), stub_gen)?;
+            let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
+            let f2 = try_numeric_result!(result_f(&n2), stub_gen)?;
 
             Ok(Number::Float(cmp::min(OrderedFloat(f1), OrderedFloat(f2))))
         }
@@ -1314,7 +1314,7 @@ impl MachineState {
                     self.interms.push(Number::Fixnum(n));
                 }
                 (HeapCellValueTag::F64, fl) => {
-                    self.interms.push(Number::Float(**fl));
+                    self.interms.push(Number::Float(*fl));
                 }
                 (HeapCellValueTag::Cons, ptr) => {
                     match_untyped_arena_ptr!(ptr,
@@ -1324,9 +1324,6 @@ impl MachineState {
                          (ArenaHeaderTag::Rational, r) => {
                              self.interms.push(Number::Rational(r));
                          }
-                         (ArenaHeaderTag::F64, fl) => {
-                             self.interms.push(Number::Float(*fl));
-                         }
                          _ => {
                              std::mem::drop(iter);
 
index cb3dbe59439a9eb0dd2440f4311fe22d46d54b95..d81cb600d1541e98aecbb3a6b15d248f1edb7123 100644 (file)
@@ -163,8 +163,7 @@ impl MachineState {
         match self.get_number(&at)? {
             Number::Fixnum(n) => self.unify_fixnum(n, n1),
             Number::Float(n) => {
-                // TODO: argghh.. allocate floats to their own area.
-                let n = arena_alloc!(n, &mut self.arena);
+                let n = float_alloc!(n.into_inner(), self.arena);
                 self.unify_f64(n, n1)
             }
             Number::Integer(n) => self.unify_big_int(n, n1),
@@ -366,8 +365,7 @@ impl Machine {
                         }
                         (HeapCellValueTag::Cons, ptr) => {
                             match ptr.get_tag() {
-                                ArenaHeaderTag::Rational | ArenaHeaderTag::Integer |
-                                ArenaHeaderTag::F64 => {
+                                ArenaHeaderTag::Rational | ArenaHeaderTag::Integer => {
                                     c
                                 }
                                 _ => {
@@ -428,9 +426,6 @@ impl Machine {
                                 (ArenaHeaderTag::Rational, r) => {
                                     Literal::Rational(r)
                                 }
-                                (ArenaHeaderTag::F64, f) => {
-                                    Literal::Float(F64Ptr(f))
-                                }
                                 (ArenaHeaderTag::Integer, n) => {
                                     Literal::Integer(n)
                                 }
index a7317cc348e4e09ecc998591704ac9cc4ff7acd1..5f9d4909f34f68b8ceebb21115ee42e591b15cd5 100644 (file)
@@ -5,7 +5,6 @@ use crate::machine::partial_string::*;
 use crate::parser::ast::*;
 use crate::types::*;
 
-use ordered_float::OrderedFloat;
 use rug::{Integer, Rational};
 
 use std::convert::TryFrom;
@@ -66,10 +65,6 @@ impl TryFrom<HeapCellValue> for Literal {
                      (ArenaHeaderTag::Rational, n) => {
                          Ok(Literal::Rational(n))
                      }
-                     (ArenaHeaderTag::F64, f) => {
-                         // remove this redundancy.
-                         Ok(Literal::Float(F64Ptr(f)))
-                     }
                      _ => {
                          Err(())
                      }
index 7519c69e1c0020915c951ec014bfcc7e7003bd20..51c8782b6909203d7123e09f282d85413951f4e6 100644 (file)
@@ -14,8 +14,6 @@ use crate::machine::stack::*;
 use crate::parser::ast::*;
 use crate::parser::rug::{Integer, Rational};
 
-use ordered_float::*;
-
 use indexmap::IndexSet;
 
 use std::cmp::Ordering;
@@ -673,7 +671,7 @@ impl MachineState {
 
     pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
         if let Some(r) = value.as_var() {
-            self.bind(r, typed_arena_ptr_as_cell!(f1));
+            self.bind(r, HeapCellValue::from(f1));
             return;
         }
 
@@ -681,16 +679,6 @@ impl MachineState {
             (HeapCellValueTag::F64, f2) => {
                 self.fail = **f1 != **f2;
             }
-            (HeapCellValueTag::Cons, cons_ptr) => {
-                match_untyped_arena_ptr!(cons_ptr,
-                     (ArenaHeaderTag::F64, f2) => {
-                         self.fail = **f1 != **F64Ptr(f2);
-                     }
-                     _ => {
-                         self.fail = true;
-                     }
-                );
-            }
             _ => {
                 self.fail = true;
             }
index 138dbdaf939a98d4437a1bfebe94a6a30ac79435..a184d0dec67658fdbf68f0af9834926475c81d20 100644 (file)
@@ -609,7 +609,6 @@ mod tests {
 
     #[test]
     fn test_term_compare() {
-        use ordered_float::OrderedFloat;
         use std::cmp::Ordering;
 
         let mut wam = MachineState::new();
@@ -777,9 +776,7 @@ mod tests {
             Some(Ordering::Greater)
         );
 
-        let one_p_one = typed_arena_ptr_as_cell!(
-            arena_alloc!(OrderedFloat(1.1), &mut wam.arena)
-        );
+        let one_p_one = HeapCellValue::from(float_alloc!(1.1, &mut wam.arena));
 
         assert_eq!(
             compare_term_test!(
index 383b6347a8af202ef460df3b5898f3121e5db153..9602dc386a8fe5e5fef143384c97e1f0394099ac 100644 (file)
@@ -3232,7 +3232,7 @@ impl Machine {
     #[inline(always)]
     pub(crate) fn cpu_now(&mut self) {
         let secs = ProcessTime::now().as_duration().as_secs_f64();
-        let secs = arena_alloc!(OrderedFloat(secs), &mut self.machine_st.arena);
+        let secs = float_alloc!(secs, self.machine_st.arena);
 
         self.machine_st.unify_f64(secs, self.machine_st.registers[1]);
     }
index 22968005f5c72577c3bd99e2fe163ba2584305b1..e341647bff7743eab981eb6e6672b1f3e1660d3b 100644 (file)
@@ -87,21 +87,8 @@ macro_rules! cell_as_atom_cell {
 
 macro_rules! cell_as_f64_ptr {
     ($cell:expr) => {{
-        let cons_ptr = ConsPtr::from_bytes($cell.into_bytes());
-
-        match cons_ptr.get_tag() {
-            ConsPtrMaskTag::F64 => {
-                F64Ptr(TypedArenaPtr::new(
-                    cons_ptr.as_ptr() as *mut OrderedFloat<f64>
-                ))
-            }
-            ConsPtrMaskTag::Cons => {
-                let ptr = cell_as_untyped_arena_ptr!($cell).payload_offset();
-                unsafe {
-                    F64Ptr(TypedArenaPtr::new(std::mem::transmute(ptr)))
-                }
-            }
-        }
+        let offset = $cell.get_value();
+        F64Ptr::from_offset(offset)
     }};
 }
 
@@ -257,13 +244,6 @@ macro_rules! match_untyped_arena_ptr_pat_body {
         #[allow(unused_braces)]
         $code
     }};
-    ($ptr:ident, F64, $n:ident, $code:expr) => {{
-        let payload_ptr =
-            unsafe { std::mem::transmute::<_, *mut OrderedFloat<f64>>($ptr.payload_offset()) };
-        let $n = TypedArenaPtr::new(payload_ptr);
-        #[allow(unused_braces)]
-        $code
-    }};
     ($ptr:ident, Rational, $n:ident, $code:expr) => {{
         let payload_ptr = unsafe { std::mem::transmute::<_, *mut Rational>($ptr.payload_offset()) };
         let $n = TypedArenaPtr::new(payload_ptr);
index 4c541016254e20f0e751bf104279b4c249560bf6..02bbd1d1cb86120b96bf734fc387dc42cd0793df 100644 (file)
@@ -1,5 +1,4 @@
 use lexical::parse_lossy;
-use ordered_float::*;
 
 use crate::atom_table::*;
 pub use crate::machine::machine_state::*;
@@ -633,12 +632,8 @@ impl<'a, R: CharRead> Lexer<'a, R> {
 
     fn vacate_with_float(&mut self, mut token: String) -> Result<Token, ParserError> {
         self.return_char(token.pop().unwrap());
-
-        let result = OrderedFloat(parse_lossy::<f64, _>(token.as_bytes())?);
-        Ok(Token::Literal(Literal::Float(arena_alloc!(
-            result,
-            &mut self.machine_st.arena
-        ))))
+        let n = parse_lossy::<f64, _>(token.as_bytes())?;
+        Ok(Token::Literal(Literal::Float(float_alloc!(n, self.machine_st.arena))))
     }
 
     fn skip_underscore_in_number(&mut self) -> Result<char, ParserError> {
@@ -748,20 +743,18 @@ impl<'a, R: CharRead> Lexer<'a, R> {
                             }
                         }
 
-                        let n = OrderedFloat(parse_lossy::<f64, _>(token.as_bytes())?);
-                        Ok(Token::Literal(Literal::Float(arena_alloc!(
-                            n,
-                            &mut self.machine_st.arena
-                        ))))
+                        let n = parse_lossy::<f64, _>(token.as_bytes())?;
+                        Ok(Token::Literal(Literal::Float(
+                            float_alloc!(n, self.machine_st.arena)
+                        )))
                     } else {
                         return Ok(self.vacate_with_float(token)?);
                     }
                 } else {
-                    let n = OrderedFloat(parse_lossy::<f64, _>(token.as_bytes())?);
-                    Ok(Token::Literal(Literal::Float(arena_alloc!(
-                        n,
-                        &mut self.machine_st.arena
-                    ))))
+                    let n = parse_lossy::<f64, _>(token.as_bytes())?;
+                    Ok(Token::Literal(Literal::Float(
+                        float_alloc!(n, self.machine_st.arena)
+                    )))
                 }
             } else {
                 self.return_char('.');
index 45f98ab84da3b9424e0e1541be5fe10eb2d57428..431f3799cd3c4ca8e347db7f5d60bb4f2a401f16 100644 (file)
@@ -4,8 +4,6 @@ use crate::parser::ast::*;
 use crate::parser::char_reader::*;
 use crate::parser::lexer::*;
 
-use ordered_float::OrderedFloat;
-
 use rug::ops::NegAssign;
 
 use std::cell::Cell;
@@ -949,8 +947,8 @@ impl<'a, R: CharRead> Parser<'a, R> {
             }
             Token::Literal(Literal::Float(n)) => self.negate_number(
                 **n,
-                |n| OrderedFloat(-n.into_inner()),
-                |n, arena| Literal::Float(arena_alloc!(n, arena)),
+                |n| -n,
+                |n, arena| Literal::Float(float_alloc!(n, arena))
             ),
             Token::Literal(c) => {
                 if let Some(name) = atomize_constant(&mut self.lexer.machine_st.atom_tbl, c) {
index 3a18e845e3c8aae1d3d64234200cdd58a9040850..1d6b4b2f9905273635d3eda49f60d302bd01fb3a 100644 (file)
@@ -15,9 +15,6 @@ use std::ops::{Add, Sub, SubAssign};
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[bits = 6]
 pub enum HeapCellValueTag {
-    // non-constants / tags with adjoining forwarding bits.
-    Cons = 0b00,
-    F64 = 0b01,
     Str = 0b000010,
     Lis = 0b000011,
     Var = 0b000110,
@@ -26,6 +23,8 @@ pub enum HeapCellValueTag {
     PStrLoc = 0b111111,
     PStrOffset = 0b001110,
     // constants.
+    Cons = 0b0,
+    F64  = 0b000001,
     Fixnum = 0b010010,
     Char = 0b011011,
     Atom = 0b001010,
@@ -36,9 +35,6 @@ pub enum HeapCellValueTag {
 #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[bits = 6]
 pub enum HeapCellValueView {
-    // non-constants / tags with adjoining forwarding bits.
-    Cons = 0b00,
-    F64 = 0b01,
     Str = 0b000010,
     Lis = 0b000011,
     Var = 0b000110,
@@ -47,6 +43,8 @@ pub enum HeapCellValueView {
     PStrLoc = 0b111111,
     PStrOffset = 0b001110,
     // constants.
+    Cons = 0b00,
+    F64  = 0b000001,
     Fixnum = 0b010010,
     Char = 0b011011,
     Atom = 0b001010,
@@ -66,7 +64,6 @@ pub enum HeapCellValueView {
 #[bits = 2]
 pub enum ConsPtrMaskTag {
     Cons = 0b00,
-    F64 = 0b01,
 }
 
 #[bitfield]
@@ -303,11 +300,9 @@ impl<T> From<TypedArenaPtr<T>> for HeapCellValue {
 impl From<F64Ptr> for HeapCellValue {
     #[inline]
     fn from(f64_ptr: F64Ptr) -> HeapCellValue {
-        HeapCellValue::from_bytes(
-            ConsPtr::from(f64_ptr.as_ptr() as u64)
-                .with_tag(ConsPtrMaskTag::F64)
-                .with_m(false)
-                .into_bytes(),
+        HeapCellValue::build_with(
+            HeapCellValueTag::F64,
+            f64_ptr.as_offset() as u64,
         )
     }
 }
@@ -327,8 +322,10 @@ impl From<ConsPtr> for HeapCellValue {
 impl<'a> From<(Number, &mut Arena)> for HeapCellValue {
     #[inline(always)]
     fn from((n, arena): (Number, &mut Arena)) -> HeapCellValue {
+        use ordered_float::OrderedFloat;
+
         match n {
-            Number::Float(n) => HeapCellValue::from(arena_alloc!(n, arena)),
+            Number::Float(OrderedFloat(n)) => HeapCellValue::from(float_alloc!(n, arena)),
             Number::Integer(n) => HeapCellValue::from(n),
             Number::Rational(n) => HeapCellValue::from(n),
             Number::Fixnum(n) => fixnum_as_cell!(n),
@@ -501,7 +498,6 @@ impl HeapCellValue {
             Ok(tag) => tag,
             Err(_) => match ConsPtr::from_bytes(self.into_bytes()).tag() {
                 ConsPtrMaskTag::Cons => HeapCellValueTag::Cons,
-                ConsPtrMaskTag::F64 => HeapCellValueTag::F64,
             },
         }
     }
@@ -569,7 +565,7 @@ impl HeapCellValue {
     #[inline]
     pub fn get_mark_bit(self) -> bool {
         match self.get_tag() {
-            HeapCellValueTag::Cons | HeapCellValueTag::F64 => {
+            HeapCellValueTag::Cons => {
                 ConsPtr::from_bytes(self.into_bytes()).m()
             }
             _ => self.m(),
@@ -579,7 +575,7 @@ impl HeapCellValue {
     #[inline]
     pub fn set_mark_bit(&mut self, m: bool) {
         match self.get_tag() {
-            HeapCellValueTag::Cons | HeapCellValueTag::F64 => {
+            HeapCellValueTag::Cons => {
                 let value = ConsPtr::from_bytes(self.into_bytes()).with_m(m);
                 *self = HeapCellValue::from_bytes(value.into_bytes());
             }