allocate floats in dedicated buffer

This commit is contained in:
Mark Thom
2022-04-04 23:56:30 -06:00
parent 0ab928063e
commit 8c99d748e2
14 changed files with 204 additions and 195 deletions

View File

@@ -1,6 +1,7 @@
use crate::machine::loader::LiveLoadState; use crate::machine::loader::LiveLoadState;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::raw_block::*;
use crate::read::*; use crate::read::*;
use modular_bitfield::prelude::*; 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)] #[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq)]
#[bits = 7] #[bits = 7]
pub enum ArenaHeaderTag { pub enum ArenaHeaderTag {
F64 = 0b01,
Integer = 0b10, Integer = 0b10,
Rational = 0b11, Rational = 0b11,
OssifiedOpDir = 0b0000100, OssifiedOpDir = 0b0000100,
@@ -197,7 +298,7 @@ pub trait ArenaAllocated {
} }
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[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 { impl fmt::Display for F64Ptr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -206,41 +307,33 @@ impl fmt::Display for F64Ptr {
} }
impl Deref for F64Ptr { impl Deref for F64Ptr {
type Target = TypedArenaPtr<OrderedFloat<f64>>; type Target = OrderedFloat<f64>;
#[inline] #[inline]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 unsafe { &*self.0.as_ptr() }
} }
} }
impl DerefMut for F64Ptr { impl DerefMut for F64Ptr {
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0 unsafe { &mut *self.0.as_ptr() }
} }
} }
impl ArenaAllocated for OrderedFloat<f64> { impl F64Ptr {
type PtrToAllocated = F64Ptr; #[inline(always)]
pub fn from_offset(offset: usize) -> Self {
#[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 {
unsafe { unsafe {
ptr::write(dst, self); F64Ptr(ptr::NonNull::new_unchecked(lookup_float(offset)))
F64Ptr(TypedArenaPtr::new(dst as *mut Self))
} }
} }
#[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 { impl ArenaAllocated for Integer {
@@ -360,7 +453,10 @@ struct AllocSlab {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Arena(*mut AllocSlab); pub struct Arena {
base: *mut AllocSlab,
pub f64_tbl: F64Table,
}
unsafe impl Send for Arena {} unsafe impl Send for Arena {}
unsafe impl Sync for Arena {} unsafe impl Sync for Arena {}
@@ -368,7 +464,7 @@ unsafe impl Sync for Arena {}
impl Arena { impl Arena {
#[inline] #[inline]
pub fn new() -> Self { 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 { 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; 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()); (*slab).header = ArenaHeader::build_with(value.size() as u64, T::tag());
let offset = (*slab).payload_offset(); let offset = (*slab).payload_offset();
let result = value.copy_to_arena(offset as *mut T); let result = value.copy_to_arena(offset as *mut T);
self.0 = slab; self.base = slab;
result result
} }
@@ -442,14 +538,14 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
ArenaHeaderTag::StandardErrorStream => { ArenaHeaderTag::StandardErrorStream => {
ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardErrorStream>>()); ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardErrorStream>>());
} }
ArenaHeaderTag::F64 | ArenaHeaderTag::NullStream => { ArenaHeaderTag::NullStream => {
} }
} }
} }
impl Drop for Arena { impl Drop for Arena {
fn drop(&mut self) { fn drop(&mut self) {
let mut ptr = self.0; let mut ptr = self.base;
while !ptr.is_null() { while !ptr.is_null() {
unsafe { 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() { fn float_ptr_cast() {
let mut wam = MockWAM::new(); let mut wam = MockWAM::new();
let f = OrderedFloat(0f64); let f = 0f64;
let mut fp = arena_alloc!(f, &mut wam.machine_st.arena); let fp = float_alloc!(f, wam.machine_st.arena);
let cell = HeapCellValue::from(fp); let mut cell = HeapCellValue::from(fp);
assert_eq!(cell.get_tag(), HeapCellValueTag::F64); assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
assert_eq!(fp.get_mark_bit(), false); assert_eq!(cell.get_mark_bit(), false);
assert_eq!(**fp, f); 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, read_heap_cell!(cell,
(HeapCellValueTag::F64, ptr) => { (HeapCellValueTag::F64, ptr) => {
assert_eq!(**ptr, f) assert_eq!(OrderedFloat(*ptr), OrderedFloat(f))
} }
_ => { unreachable!() } _ => { unreachable!() }
); );
@@ -558,8 +654,8 @@ mod tests {
// integer // integer
let big_int = 2 * Integer::from(1u64 << 63); let big_int: Integer = 2 * Integer::from(1u64 << 63);
let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, &mut wam.machine_st.arena); let big_int_ptr: TypedArenaPtr<Integer> = arena_alloc!(big_int, wam.machine_st.arena);
assert!(!big_int_ptr.as_ptr().is_null()); assert!(!big_int_ptr.as_ptr().is_null());
@@ -763,22 +859,11 @@ mod tests {
// float // float
let float = OrderedFloat(3.1415926f64); let float = 3.1415926f64;
let float_ptr = arena_alloc!(float, &mut wam.machine_st.arena); let float_ptr = float_alloc!(float, wam.machine_st.arena);
let cell = HeapCellValue::from(float_ptr);
assert!(!float_ptr.as_ptr().is_null()); assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
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.
}
}
// char // char

View File

@@ -169,16 +169,16 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
match c { match c {
Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))), Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*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::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number( 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( 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( 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)), _ => 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 { pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
match n { match n {
&Number::Integer(_) | &Number::Fixnum(_) => *n, &Number::Integer(_) | &Number::Fixnum(_) => *n,
&Number::Float(OrderedFloat(f)) => { &Number::Float(f) => {
let f = f.floor(); let f = f.floor();
const I64_MIN_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64); const I64_MIN_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64);
const I64_MAX_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 { if I64_MIN_TO_F <= f && f <= I64_MAX_TO_F {
fixnum!(Number, f as i64, arena) fixnum!(Number, f.into_inner() as i64, arena)
} else { } 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) => { &Number::Rational(ref r) => {
@@ -415,23 +415,14 @@ pub(crate) fn rnd_f(n: &Number) -> f64 {
} }
// floating point result function -- 9.1.4.2. // floating point result function -- 9.1.4.2.
pub(crate) fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError> pub(crate) fn result_f(n: &Number) -> Result<f64, EvalError> {
where classify_float(rnd_f(n))
Round: Fn(&Number) -> f64,
{
let f = rnd_f(n);
classify_float(f, round)
} }
fn classify_float<Round>(f: f64, round: Round) -> Result<f64, EvalError> fn classify_float(f: f64) -> Result<f64, EvalError> {
where
Round: Fn(&Number) -> f64,
{
match f.classify() { match f.classify() {
FpCategory::Normal | FpCategory::Zero => Ok(round(&Number::Float(OrderedFloat(f)))), FpCategory::Normal | FpCategory::Zero => Ok(f),
FpCategory::Infinite => { FpCategory::Infinite => {
let f = round(&Number::Float(OrderedFloat(f)));
if OrderedFloat(f) == OrderedFloat(f64::MAX) { if OrderedFloat(f) == OrderedFloat(f64::MAX) {
Ok(f) Ok(f)
} else { } else {
@@ -439,33 +430,33 @@ where
} }
} }
FpCategory::Nan => Err(EvalError::Undefined), FpCategory::Nan => Err(EvalError::Undefined),
_ => Ok(round(&Number::Float(OrderedFloat(f)))), _ => Ok(f)
} }
} }
#[inline] #[inline]
pub(crate) fn float_fn_to_f(n: i64) -> Result<f64, EvalError> { 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] #[inline]
pub(crate) fn float_i_to_f(n: &Integer) -> Result<f64, EvalError> { 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] #[inline]
pub(crate) fn float_r_to_f(r: &Rational) -> Result<f64, EvalError> { 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] #[inline]
pub(crate) fn add_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> { 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] #[inline]
pub(crate) fn mul_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> { 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] #[inline]
@@ -473,7 +464,7 @@ fn div_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
if FpCategory::Zero == f2.classify() { if FpCategory::Zero == f2.classify() {
Err(EvalError::ZeroDivisor) Err(EvalError::ZeroDivisor)
} else { } 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, read_heap_cell!(value,
(HeapCellValueTag::Cons, c) => { (HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c, match_untyped_arena_ptr!(c,
(ArenaHeaderTag::F64, n) => {
Ok(Number::Float(*n))
}
(ArenaHeaderTag::Integer, n) => { (ArenaHeaderTag::Integer, n) => {
Ok(Number::Integer(n)) Ok(Number::Integer(n))
} }
@@ -698,7 +686,7 @@ impl TryFrom<HeapCellValue> for Number {
) )
} }
(HeapCellValueTag::F64, n) => { (HeapCellValueTag::F64, n) => {
Ok(Number::Float(**n)) Ok(Number::Float(*n))
} }
(HeapCellValueTag::Fixnum, n) => { (HeapCellValueTag::Fixnum, n) => {
Ok(Number::Fixnum(n)) Ok(Number::Fixnum(n))

View File

@@ -608,7 +608,7 @@ impl ArenaFrom<Number> for Literal {
match value { match value {
Number::Fixnum(n) => Literal::Fixnum(n), Number::Fixnum(n) => Literal::Fixnum(n),
Number::Integer(n) => Literal::Integer(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), Number::Rational(r) => Literal::Rational(r),
} }
} }
@@ -620,7 +620,7 @@ impl ArenaFrom<Number> for HeapCellValue {
match value { match value {
Number::Fixnum(n) => fixnum_as_cell!(n), Number::Fixnum(n) => fixnum_as_cell!(n),
Number::Integer(n) => typed_arena_ptr_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), Number::Rational(n) => typed_arena_ptr_as_cell!(n),
} }
} }

View File

@@ -1486,7 +1486,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Fixnum(n)), &op); self.print_number(max_depth, NumberFocus::Unfocused(Number::Fixnum(n)), &op);
} }
(HeapCellValueTag::F64, f) => { (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) => { (HeapCellValueTag::CStr | HeapCellValueTag::PStr | HeapCellValueTag::PStrOffset) => {
self.print_list_like(max_depth); self.print_list_like(max_depth);
@@ -1513,9 +1513,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
(HeapCellValueTag::Cons, c) => { (HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c, match_untyped_arena_ptr!(c,
(ArenaHeaderTag::F64, f) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Float(*f)), &op);
}
(ArenaHeaderTag::Integer, n) => { (ArenaHeaderTag::Integer, n) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op); self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op);
} }

View 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> { pub(crate) fn float_pow(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
let f1 = result_f(&n1, rnd_f); let f1 = result_f(&n1);
let f2 = result_f(&n2, rnd_f); let f2 = result_f(&n2);
let stub_gen = || { let stub_gen = || {
let pow_atom = atom!("**"); 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 f1 = try_numeric_result!(f1, stub_gen)?;
let f2 = try_numeric_result!(f2, 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!( Ok(Number::Float(OrderedFloat(try_numeric_result!(
result, stub_gen result, stub_gen
@@ -404,7 +404,7 @@ pub(crate) fn float(n: Number) -> Result<f64, MachineStubGen> {
functor_stub(is_atom, 2) functor_stub(is_atom, 2)
}; };
try_numeric_result!(result_f(&n, rnd_f), stub_gen) try_numeric_result!(result_f(&n), stub_gen)
} }
#[inline] #[inline]
@@ -420,8 +420,8 @@ where
functor_stub(is_atom, 2) functor_stub(is_atom, 2)
}; };
let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?; let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
let f1 = result_f(&Number::Float(OrderedFloat(f(f1))), rnd_f); let f1 = result_f(&Number::Float(OrderedFloat(f(f1))));
try_numeric_result!(f1, stub_gen) 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) functor_stub(max_atom, 2)
}; };
let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?; let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
let f2 = try_numeric_result!(result_f(&n2, rnd_f), stub_gen)?; let f2 = try_numeric_result!(result_f(&n2), stub_gen)?;
Ok(Number::Float(cmp::max(OrderedFloat(f1), OrderedFloat(f2)))) 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) functor_stub(min_atom, 2)
}; };
let f1 = try_numeric_result!(result_f(&n1, rnd_f), stub_gen)?; let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
let f2 = try_numeric_result!(result_f(&n2, rnd_f), stub_gen)?; let f2 = try_numeric_result!(result_f(&n2), stub_gen)?;
Ok(Number::Float(cmp::min(OrderedFloat(f1), OrderedFloat(f2)))) Ok(Number::Float(cmp::min(OrderedFloat(f1), OrderedFloat(f2))))
} }
@@ -1314,7 +1314,7 @@ impl MachineState {
self.interms.push(Number::Fixnum(n)); self.interms.push(Number::Fixnum(n));
} }
(HeapCellValueTag::F64, fl) => { (HeapCellValueTag::F64, fl) => {
self.interms.push(Number::Float(**fl)); self.interms.push(Number::Float(*fl));
} }
(HeapCellValueTag::Cons, ptr) => { (HeapCellValueTag::Cons, ptr) => {
match_untyped_arena_ptr!(ptr, match_untyped_arena_ptr!(ptr,
@@ -1324,9 +1324,6 @@ impl MachineState {
(ArenaHeaderTag::Rational, r) => { (ArenaHeaderTag::Rational, r) => {
self.interms.push(Number::Rational(r)); self.interms.push(Number::Rational(r));
} }
(ArenaHeaderTag::F64, fl) => {
self.interms.push(Number::Float(*fl));
}
_ => { _ => {
std::mem::drop(iter); std::mem::drop(iter);

View File

@@ -163,8 +163,7 @@ impl MachineState {
match self.get_number(&at)? { match self.get_number(&at)? {
Number::Fixnum(n) => self.unify_fixnum(n, n1), Number::Fixnum(n) => self.unify_fixnum(n, n1),
Number::Float(n) => { Number::Float(n) => {
// TODO: argghh.. allocate floats to their own area. let n = float_alloc!(n.into_inner(), self.arena);
let n = arena_alloc!(n, &mut self.arena);
self.unify_f64(n, n1) self.unify_f64(n, n1)
} }
Number::Integer(n) => self.unify_big_int(n, n1), Number::Integer(n) => self.unify_big_int(n, n1),
@@ -366,8 +365,7 @@ impl Machine {
} }
(HeapCellValueTag::Cons, ptr) => { (HeapCellValueTag::Cons, ptr) => {
match ptr.get_tag() { match ptr.get_tag() {
ArenaHeaderTag::Rational | ArenaHeaderTag::Integer | ArenaHeaderTag::Rational | ArenaHeaderTag::Integer => {
ArenaHeaderTag::F64 => {
c c
} }
_ => { _ => {
@@ -428,9 +426,6 @@ impl Machine {
(ArenaHeaderTag::Rational, r) => { (ArenaHeaderTag::Rational, r) => {
Literal::Rational(r) Literal::Rational(r)
} }
(ArenaHeaderTag::F64, f) => {
Literal::Float(F64Ptr(f))
}
(ArenaHeaderTag::Integer, n) => { (ArenaHeaderTag::Integer, n) => {
Literal::Integer(n) Literal::Integer(n)
} }

View File

@@ -5,7 +5,6 @@ use crate::machine::partial_string::*;
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::types::*; use crate::types::*;
use ordered_float::OrderedFloat;
use rug::{Integer, Rational}; use rug::{Integer, Rational};
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -66,10 +65,6 @@ impl TryFrom<HeapCellValue> for Literal {
(ArenaHeaderTag::Rational, n) => { (ArenaHeaderTag::Rational, n) => {
Ok(Literal::Rational(n)) Ok(Literal::Rational(n))
} }
(ArenaHeaderTag::F64, f) => {
// remove this redundancy.
Ok(Literal::Float(F64Ptr(f)))
}
_ => { _ => {
Err(()) Err(())
} }

View File

@@ -14,8 +14,6 @@ use crate::machine::stack::*;
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::parser::rug::{Integer, Rational}; use crate::parser::rug::{Integer, Rational};
use ordered_float::*;
use indexmap::IndexSet; use indexmap::IndexSet;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -673,7 +671,7 @@ impl MachineState {
pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) { pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
if let Some(r) = value.as_var() { if let Some(r) = value.as_var() {
self.bind(r, typed_arena_ptr_as_cell!(f1)); self.bind(r, HeapCellValue::from(f1));
return; return;
} }
@@ -681,16 +679,6 @@ impl MachineState {
(HeapCellValueTag::F64, f2) => { (HeapCellValueTag::F64, f2) => {
self.fail = **f1 != **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; self.fail = true;
} }

View File

@@ -609,7 +609,6 @@ mod tests {
#[test] #[test]
fn test_term_compare() { fn test_term_compare() {
use ordered_float::OrderedFloat;
use std::cmp::Ordering; use std::cmp::Ordering;
let mut wam = MachineState::new(); let mut wam = MachineState::new();
@@ -777,9 +776,7 @@ mod tests {
Some(Ordering::Greater) Some(Ordering::Greater)
); );
let one_p_one = typed_arena_ptr_as_cell!( let one_p_one = HeapCellValue::from(float_alloc!(1.1, &mut wam.arena));
arena_alloc!(OrderedFloat(1.1), &mut wam.arena)
);
assert_eq!( assert_eq!(
compare_term_test!( compare_term_test!(

View File

@@ -3232,7 +3232,7 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn cpu_now(&mut self) { pub(crate) fn cpu_now(&mut self) {
let secs = ProcessTime::now().as_duration().as_secs_f64(); 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]); self.machine_st.unify_f64(secs, self.machine_st.registers[1]);
} }

View File

@@ -87,21 +87,8 @@ macro_rules! cell_as_atom_cell {
macro_rules! cell_as_f64_ptr { macro_rules! cell_as_f64_ptr {
($cell:expr) => {{ ($cell:expr) => {{
let cons_ptr = ConsPtr::from_bytes($cell.into_bytes()); let offset = $cell.get_value();
F64Ptr::from_offset(offset)
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)))
}
}
}
}}; }};
} }
@@ -257,13 +244,6 @@ macro_rules! match_untyped_arena_ptr_pat_body {
#[allow(unused_braces)] #[allow(unused_braces)]
$code $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) => {{ ($ptr:ident, Rational, $n:ident, $code:expr) => {{
let payload_ptr = unsafe { std::mem::transmute::<_, *mut Rational>($ptr.payload_offset()) }; let payload_ptr = unsafe { std::mem::transmute::<_, *mut Rational>($ptr.payload_offset()) };
let $n = TypedArenaPtr::new(payload_ptr); let $n = TypedArenaPtr::new(payload_ptr);

View File

@@ -1,5 +1,4 @@
use lexical::parse_lossy; use lexical::parse_lossy;
use ordered_float::*;
use crate::atom_table::*; use crate::atom_table::*;
pub use crate::machine::machine_state::*; 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> { fn vacate_with_float(&mut self, mut token: String) -> Result<Token, ParserError> {
self.return_char(token.pop().unwrap()); self.return_char(token.pop().unwrap());
let n = parse_lossy::<f64, _>(token.as_bytes())?;
let result = OrderedFloat(parse_lossy::<f64, _>(token.as_bytes())?); Ok(Token::Literal(Literal::Float(float_alloc!(n, self.machine_st.arena))))
Ok(Token::Literal(Literal::Float(arena_alloc!(
result,
&mut self.machine_st.arena
))))
} }
fn skip_underscore_in_number(&mut self) -> Result<char, ParserError> { 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())?); let n = parse_lossy::<f64, _>(token.as_bytes())?;
Ok(Token::Literal(Literal::Float(arena_alloc!( Ok(Token::Literal(Literal::Float(
n, float_alloc!(n, self.machine_st.arena)
&mut self.machine_st.arena )))
))))
} else { } else {
return Ok(self.vacate_with_float(token)?); return Ok(self.vacate_with_float(token)?);
} }
} else { } else {
let n = OrderedFloat(parse_lossy::<f64, _>(token.as_bytes())?); let n = parse_lossy::<f64, _>(token.as_bytes())?;
Ok(Token::Literal(Literal::Float(arena_alloc!( Ok(Token::Literal(Literal::Float(
n, float_alloc!(n, self.machine_st.arena)
&mut self.machine_st.arena )))
))))
} }
} else { } else {
self.return_char('.'); self.return_char('.');

View File

@@ -4,8 +4,6 @@ use crate::parser::ast::*;
use crate::parser::char_reader::*; use crate::parser::char_reader::*;
use crate::parser::lexer::*; use crate::parser::lexer::*;
use ordered_float::OrderedFloat;
use rug::ops::NegAssign; use rug::ops::NegAssign;
use std::cell::Cell; use std::cell::Cell;
@@ -949,8 +947,8 @@ impl<'a, R: CharRead> Parser<'a, R> {
} }
Token::Literal(Literal::Float(n)) => self.negate_number( Token::Literal(Literal::Float(n)) => self.negate_number(
**n, **n,
|n| OrderedFloat(-n.into_inner()), |n| -n,
|n, arena| Literal::Float(arena_alloc!(n, arena)), |n, arena| Literal::Float(float_alloc!(n, arena))
), ),
Token::Literal(c) => { Token::Literal(c) => {
if let Some(name) = atomize_constant(&mut self.lexer.machine_st.atom_tbl, c) { if let Some(name) = atomize_constant(&mut self.lexer.machine_st.atom_tbl, c) {

View File

@@ -15,9 +15,6 @@ 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 {
// non-constants / tags with adjoining forwarding bits.
Cons = 0b00,
F64 = 0b01,
Str = 0b000010, Str = 0b000010,
Lis = 0b000011, Lis = 0b000011,
Var = 0b000110, Var = 0b000110,
@@ -26,6 +23,8 @@ pub enum HeapCellValueTag {
PStrLoc = 0b111111, PStrLoc = 0b111111,
PStrOffset = 0b001110, PStrOffset = 0b001110,
// constants. // constants.
Cons = 0b0,
F64 = 0b000001,
Fixnum = 0b010010, Fixnum = 0b010010,
Char = 0b011011, Char = 0b011011,
Atom = 0b001010, Atom = 0b001010,
@@ -36,9 +35,6 @@ pub enum HeapCellValueTag {
#[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 {
// non-constants / tags with adjoining forwarding bits.
Cons = 0b00,
F64 = 0b01,
Str = 0b000010, Str = 0b000010,
Lis = 0b000011, Lis = 0b000011,
Var = 0b000110, Var = 0b000110,
@@ -47,6 +43,8 @@ pub enum HeapCellValueView {
PStrLoc = 0b111111, PStrLoc = 0b111111,
PStrOffset = 0b001110, PStrOffset = 0b001110,
// constants. // constants.
Cons = 0b00,
F64 = 0b000001,
Fixnum = 0b010010, Fixnum = 0b010010,
Char = 0b011011, Char = 0b011011,
Atom = 0b001010, Atom = 0b001010,
@@ -66,7 +64,6 @@ pub enum HeapCellValueView {
#[bits = 2] #[bits = 2]
pub enum ConsPtrMaskTag { pub enum ConsPtrMaskTag {
Cons = 0b00, Cons = 0b00,
F64 = 0b01,
} }
#[bitfield] #[bitfield]
@@ -303,11 +300,9 @@ impl<T> From<TypedArenaPtr<T>> for HeapCellValue {
impl From<F64Ptr> for HeapCellValue { impl From<F64Ptr> for HeapCellValue {
#[inline] #[inline]
fn from(f64_ptr: F64Ptr) -> HeapCellValue { fn from(f64_ptr: F64Ptr) -> HeapCellValue {
HeapCellValue::from_bytes( HeapCellValue::build_with(
ConsPtr::from(f64_ptr.as_ptr() as u64) HeapCellValueTag::F64,
.with_tag(ConsPtrMaskTag::F64) f64_ptr.as_offset() as u64,
.with_m(false)
.into_bytes(),
) )
} }
} }
@@ -327,8 +322,10 @@ impl From<ConsPtr> for HeapCellValue {
impl<'a> From<(Number, &mut Arena)> for HeapCellValue { impl<'a> From<(Number, &mut Arena)> for HeapCellValue {
#[inline(always)] #[inline(always)]
fn from((n, arena): (Number, &mut Arena)) -> HeapCellValue { fn from((n, arena): (Number, &mut Arena)) -> HeapCellValue {
use ordered_float::OrderedFloat;
match n { 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::Integer(n) => HeapCellValue::from(n),
Number::Rational(n) => HeapCellValue::from(n), Number::Rational(n) => HeapCellValue::from(n),
Number::Fixnum(n) => fixnum_as_cell!(n), Number::Fixnum(n) => fixnum_as_cell!(n),
@@ -501,7 +498,6 @@ impl HeapCellValue {
Ok(tag) => tag, Ok(tag) => tag,
Err(_) => match ConsPtr::from_bytes(self.into_bytes()).tag() { Err(_) => match ConsPtr::from_bytes(self.into_bytes()).tag() {
ConsPtrMaskTag::Cons => HeapCellValueTag::Cons, ConsPtrMaskTag::Cons => HeapCellValueTag::Cons,
ConsPtrMaskTag::F64 => HeapCellValueTag::F64,
}, },
} }
} }
@@ -569,7 +565,7 @@ impl HeapCellValue {
#[inline] #[inline]
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::F64 => { HeapCellValueTag::Cons => {
ConsPtr::from_bytes(self.into_bytes()).m() ConsPtr::from_bytes(self.into_bytes()).m()
} }
_ => self.m(), _ => self.m(),
@@ -579,7 +575,7 @@ impl HeapCellValue {
#[inline] #[inline]
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::F64 => { HeapCellValueTag::Cons => {
let value = ConsPtr::from_bytes(self.into_bytes()).with_m(m); let value = ConsPtr::from_bytes(self.into_bytes()).with_m(m);
*self = HeapCellValue::from_bytes(value.into_bytes()); *self = HeapCellValue::from_bytes(value.into_bytes());
} }