From: Mark Thom Date: Tue, 5 Apr 2022 05:56:30 +0000 (-0600) Subject: allocate floats in dedicated buffer X-Git-Tag: v0.9.1~75 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=8c99d748e28385cafb30c141521ec10c814ad4d9;p=scryer-prolog.git allocate floats in dedicated buffer --- diff --git a/src/arena.rs b/src/arena.rs index f7490b66..bf290f6c 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -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, +} + +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 { + 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::()); + + 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>); +pub struct F64Ptr(pub ptr::NonNull>); 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>; + type Target = OrderedFloat; #[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 { - type PtrToAllocated = F64Ptr; - - #[inline] - fn tag() -> ArenaHeaderTag { - ArenaHeaderTag::F64 - } - - #[inline] - fn size(&self) -> usize { - mem::size_of::() - } - - #[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(&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::>()); } - 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 = arena_alloc!(big_int, &mut wam.machine_st.arena); + let big_int: Integer = 2 * Integer::from(1u64 << 63); + let big_int_ptr: TypedArenaPtr = 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 diff --git a/src/arithmetic.rs b/src/arithmetic.rs index cc0b0194..d4fa8e38 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -169,16 +169,16 @@ fn push_literal(interm: &mut Vec, 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 = OrderedFloat(i64::MIN as f64); const I64_MAX_TO_F: OrderedFloat = 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(n: &Number, round: Round) -> Result -where - Round: Fn(&Number) -> f64, -{ - let f = rnd_f(n); - classify_float(f, round) +pub(crate) fn result_f(n: &Number) -> Result { + classify_float(rnd_f(n)) } -fn classify_float(f: f64, round: Round) -> Result -where - Round: Fn(&Number) -> f64, -{ +fn classify_float(f: f64) -> Result { 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 { - classify_float(n as f64, rnd_f) + classify_float(n as f64) } #[inline] pub(crate) fn float_i_to_f(n: &Integer) -> Result { - classify_float(n.to_f64(), rnd_f) + classify_float(n.to_f64()) } #[inline] pub(crate) fn float_r_to_f(r: &Rational) -> Result { - classify_float(r.to_f64(), rnd_f) + classify_float(r.to_f64()) } #[inline] pub(crate) fn add_f(f1: f64, f2: f64) -> Result, 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, 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, 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 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 for Number { ) } (HeapCellValueTag::F64, n) => { - Ok(Number::Float(**n)) + Ok(Number::Float(*n)) } (HeapCellValueTag::Fixnum, n) => { Ok(Number::Fixnum(n)) diff --git a/src/forms.rs b/src/forms.rs index 1b61546a..f1c634bc 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -608,7 +608,7 @@ impl ArenaFrom 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 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), } } diff --git a/src/heap_print.rs b/src/heap_print.rs index 86db4bee..fa9c2fca 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -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); } diff --git a/src/machine/arithmetic_ops.rs b/src/machine/arithmetic_ops.rs index 2c90cc61..473f6295 100644 --- a/src/machine/arithmetic_ops.rs +++ b/src/machine/arithmetic_ops.rs @@ -281,8 +281,8 @@ pub(crate) fn div(n1: Number, n2: Number) -> Result { } pub(crate) fn float_pow(n1: Number, n2: Number) -> Result { - 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 Result { 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 { 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 { 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); diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index cb3dbe59..d81cb600 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -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) } diff --git a/src/machine/heap.rs b/src/machine/heap.rs index a7317cc3..5f9d4909 100644 --- a/src/machine/heap.rs +++ b/src/machine/heap.rs @@ -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 for Literal { (ArenaHeaderTag::Rational, n) => { Ok(Literal::Rational(n)) } - (ArenaHeaderTag::F64, f) => { - // remove this redundancy. - Ok(Literal::Float(F64Ptr(f))) - } _ => { Err(()) } diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 7519c69e..51c8782b 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -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; } diff --git a/src/machine/mock_wam.rs b/src/machine/mock_wam.rs index 138dbdaf..a184d0de 100644 --- a/src/machine/mock_wam.rs +++ b/src/machine/mock_wam.rs @@ -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!( diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 383b6347..9602dc38 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -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]); } diff --git a/src/macros.rs b/src/macros.rs index 22968005..e341647b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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 - )) - } - 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>($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); diff --git a/src/parser/lexer.rs b/src/parser/lexer.rs index 4c541016..02bbd1d1 100644 --- a/src/parser/lexer.rs +++ b/src/parser/lexer.rs @@ -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 { self.return_char(token.pop().unwrap()); - - let result = OrderedFloat(parse_lossy::(token.as_bytes())?); - Ok(Token::Literal(Literal::Float(arena_alloc!( - result, - &mut self.machine_st.arena - )))) + let n = parse_lossy::(token.as_bytes())?; + Ok(Token::Literal(Literal::Float(float_alloc!(n, self.machine_st.arena)))) } fn skip_underscore_in_number(&mut self) -> Result { @@ -748,20 +743,18 @@ impl<'a, R: CharRead> Lexer<'a, R> { } } - let n = OrderedFloat(parse_lossy::(token.as_bytes())?); - Ok(Token::Literal(Literal::Float(arena_alloc!( - n, - &mut self.machine_st.arena - )))) + let n = parse_lossy::(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::(token.as_bytes())?); - Ok(Token::Literal(Literal::Float(arena_alloc!( - n, - &mut self.machine_st.arena - )))) + let n = parse_lossy::(token.as_bytes())?; + Ok(Token::Literal(Literal::Float( + float_alloc!(n, self.machine_st.arena) + ))) } } else { self.return_char('.'); diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 45f98ab8..431f3799 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -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) { diff --git a/src/types.rs b/src/types.rs index 3a18e845..1d6b4b2f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -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 From> for HeapCellValue { impl From 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 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()); }