]> Repositorios git - scryer-prolog.git/commitdiff
use raw_block.rs for the heap backend
authorMark Thom <[email protected]>
Sun, 16 Feb 2020 23:30:36 +0000 (16:30 -0700)
committerMark Thom <[email protected]>
Sun, 16 Feb 2020 23:30:36 +0000 (16:30 -0700)
12 files changed:
src/prolog/machine/dynamic_database.rs
src/prolog/machine/heap.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/raw_block.rs
src/prolog/machine/stack.rs
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/read.rs

index f76601bf20e93c7122508225632f605d27413825..44871b4c6e3e210a81b8c303e36d3af210a87e12 100644 (file)
@@ -134,7 +134,7 @@ impl Machine {
         self.machine_st = machine_st;
 
         if let EvalSession::Error(err) = result {
-            let h = self.machine_st.heap.h;
+            let h = self.machine_st.heap.h();
             let stub = MachineError::functor_stub(src, 1);
             let err = MachineError::session_error(h, err);
             let err = self.machine_st.error_form(err, stub);
index da3cc2182655a76d6c6fb4819868491431409b2f..b3d406e3e636c34d99820c96cc5a3ff7d5ea3ce3 100644 (file)
-use prolog_parser::ast::*;
+use core::marker::PhantomData;
+
+use crate::prolog_parser::ast::*;
 
 use crate::prolog::machine::machine_indices::*;
+use crate::prolog::machine::raw_block::*;
 
 use std::mem;
 use std::ops::{Index, IndexMut};
+use std::ptr;
+
+pub(crate) struct StandardHeapTraits {}
+
+impl RawBlockTraits for StandardHeapTraits {
+    #[inline]
+    fn init_size() -> usize {
+        256 * mem::size_of::<HeapCellValue>()
+    }
+
+    #[inline]
+    fn align() -> usize {
+        mem::align_of::<HeapCellValue>()
+    }
+}
 
-pub struct Heap {
-    heap: Vec<HeapCellValue>,
-    pub h: usize,
+pub(crate) struct HeapTemplate<T: RawBlockTraits> {
+    buf: RawBlock<T>,
+    _marker: PhantomData<HeapCellValue>,
 }
 
-impl Heap {
-    pub fn with_capacity(cap: usize) -> Self {
-        Heap {
-            heap: Vec::with_capacity(cap),
-            h: 0,
+pub(crate) type Heap = HeapTemplate<StandardHeapTraits>;
+
+impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
+    fn drop(&mut self) {
+        self.clear();
+        self.buf.deallocate();
+    }
+}
+
+pub(crate)
+struct HeapIntoIterator<T: RawBlockTraits> {
+    offset: usize,
+    buf: RawBlock<T>,
+}
+
+impl<T: RawBlockTraits> Drop for HeapIntoIterator<T> {
+    fn drop(&mut self) {
+        let mut heap =
+            HeapTemplate { buf: self.buf.take(), _marker: PhantomData };
+
+        heap.truncate(self.offset / mem::size_of::<HeapCellValue>());
+        heap.buf.deallocate();
+    }
+}
+
+impl<T: RawBlockTraits> Iterator for HeapIntoIterator<T> {
+    type Item = HeapCellValue;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let ptr = self.buf.base as usize + self.offset;
+        self.offset += mem::size_of::<HeapCellValue>();
+
+        if ptr < self.buf.top as usize {
+            unsafe {
+                Some(ptr::read(ptr as *const HeapCellValue))
+            }
+        } else {
+            None
         }
     }
+}
 
-    #[inline]
-    pub fn push(&mut self, val: HeapCellValue) {
-        self.heap.push(val);
-        self.h += 1;
+pub(crate)
+struct HeapIterator<'a, T: RawBlockTraits> {
+    offset: usize,
+    buf: &'a RawBlock<T>,
+}
+
+impl<'a, T: RawBlockTraits> HeapIterator<'a, T> {
+    pub(crate)
+    fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
+        HeapIterator { buf, offset }
     }
+}
 
-    #[inline]
-    pub(crate) fn take(&mut self) -> Self {
-        let h = self.h;
-        self.h = 0;
+impl<'a, T: RawBlockTraits> Iterator for HeapIterator<'a, T> {
+    type Item = &'a HeapCellValue;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let ptr = self.buf.base as usize + self.offset;
+        self.offset += mem::size_of::<HeapCellValue>();
 
-        Heap {
-            heap: mem::replace(&mut self.heap, vec![]),
-            h,
+        if ptr < self.buf.top as usize {
+            unsafe {
+                Some(&*(ptr as *const _))
+            }
+        } else {
+            None
         }
     }
+}
 
+pub(crate)
+struct HeapIteratorMut<'a, T: RawBlockTraits> {
+    offset: usize,
+    buf: &'a mut RawBlock<T>,
+}
+
+impl<'a, T: RawBlockTraits> HeapIteratorMut<'a, T> {
+    pub(crate)
+    fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
+        HeapIteratorMut { buf, offset }
+    }
+}
+
+impl<'a, T: RawBlockTraits> Iterator for HeapIteratorMut<'a, T> {
+    type Item = &'a mut HeapCellValue;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let ptr = self.buf.base as usize + self.offset;
+        self.offset += mem::size_of::<HeapCellValue>();
+
+        if ptr < self.buf.top as usize {
+            unsafe {
+                Some(&mut *(ptr as *mut _))
+            }
+        } else {
+            None
+        }
+    }
+}
+
+impl<T: RawBlockTraits> HeapTemplate<T> {
     #[inline]
-    pub fn truncate(&mut self, h: usize) {
-        self.h = h;
-        self.heap.truncate(h);
+    pub(crate)
+    fn new() -> Self {
+        HeapTemplate { buf: RawBlock::new(), _marker: PhantomData }
     }
 
     #[inline]
-    pub fn last(&self) -> Option<&HeapCellValue> {
-        self.heap.last()
+    pub(crate)
+    fn push(&mut self, val: HeapCellValue) {
+        unsafe {
+            let new_top = self.buf.new_block(mem::size_of::<HeapCellValue>());
+            ptr::write(self.buf.top as *mut _, val);
+            self.buf.top = new_top;
+        }
     }
 
     #[inline]
-    pub fn len(&self) -> usize {
-        self.heap.len()
+    pub(crate)
+    fn take<U: RawBlockTraits>(&mut self) -> HeapTemplate<U> {
+        unsafe {
+            HeapTemplate {
+                buf: mem::transmute::<RawBlock<T>, RawBlock<U>>(self.buf.take()),
+                _marker: PhantomData,
+            }
+        }
+    }
+
+    #[inline]
+    pub(crate)
+    fn truncate(&mut self, h: usize) {
+        let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize;
+        let mut h = new_top;
+
+        unsafe {
+            while h as *const _ < self.buf.top {
+                let val = h as *mut HeapCellValue;
+                ptr::drop_in_place(val);
+                h += mem::size_of::<HeapCellValue>();
+            }
+        }
+
+        self.buf.top = new_top as *const _;
     }
 
-    pub fn append(&mut self, vals: Vec<HeapCellValue>) {
-        let n = vals.len();
+    #[inline]
+    pub(crate)
+    fn h(&self) -> usize {
+        (self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
+    }
 
-        self.heap.extend(vals.into_iter());
-        self.h += n;
+    pub(crate)
+    fn append(&mut self, vals: Vec<HeapCellValue>) {
+        for val in vals {
+            self.push(val);
+        }
     }
 
-    pub fn clear(&mut self) {
-        self.heap.clear();
-        self.h = 0;
+    pub(crate)
+    fn clear(&mut self) {
+        if !self.buf.base.is_null() {
+            self.truncate(0);
+            self.buf.top = self.buf.base;
+        }
     }
 
-    pub fn to_list<Iter: Iterator<Item = Addr>>(&mut self, values: Iter) -> usize {
-        let head_addr = self.h;
+    pub(crate)
+    fn to_list<Iter: Iterator<Item = Addr>>(&mut self, values: Iter) -> usize {
+        let head_addr = self.h();
 
         for value in values {
-            let h = self.h;
+            let h = self.h();
 
             self.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
             self.push(HeapCellValue::Addr(value));
         }
 
         self.push(HeapCellValue::Addr(Addr::Con(Constant::EmptyList)));
+
         head_addr
     }
 
-    pub fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
+    /* Create an iterator starting from the passed offset. */
+    pub(crate)
+    fn iter_from<'a>(&'a self, offset: usize) -> HeapIterator<'a, T> {
+        HeapIterator::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
+    }
+
+    pub(crate)
+    fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIteratorMut<'a, T> {
+        HeapIteratorMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
+    }
+
+    pub(crate)
+    fn into_iter(mut self) -> HeapIntoIterator<T> {
+        HeapIntoIterator { buf: self.buf.take(), offset: 0 }
+    }
+
+    pub(crate)
+    fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
         for hcv in iter {
             self.push(hcv);
         }
     }
 
-    pub fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
+    pub(crate)
+    fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
         let extract_integer = |s: usize| -> Option<usize> {
-            match self.heap[s].as_addr(s) {
+            match self[s].as_addr(s) {
                 Addr::Con(Constant::Integer(n)) => n.to_usize(),
                 _ => None
             }
         };
-        
+
         match addr {
             Addr::Str(s) => {
-                match &self.heap[*s] {
+                match &self[*s] {
                     HeapCellValue::NamedStr(arity, ref name, _) => {
                         match (name.as_str(), *arity) {
                             ("dir_entry", 1) => {
@@ -128,16 +281,24 @@ impl Heap {
     }
 }
 
-impl Index<usize> for Heap {
+impl<T: RawBlockTraits> Index<usize> for HeapTemplate<T> {
     type Output = HeapCellValue;
 
+    #[inline]
     fn index(&self, index: usize) -> &Self::Output {
-        &self.heap[index]
+        unsafe {
+            let ptr = self.buf.base as usize + index * mem::size_of::<HeapCellValue>();
+            &*(ptr as *const HeapCellValue)
+        }
     }
 }
 
-impl IndexMut<usize> for Heap {
+impl<T: RawBlockTraits> IndexMut<usize> for HeapTemplate<T> {
+    #[inline]
     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
-        &mut self.heap[index]
+        unsafe {
+            let ptr = self.buf.base as usize + index * mem::size_of::<HeapCellValue>();
+            &mut *(ptr as *mut HeapCellValue)
+        }
     }
 }
index 5596d71b6f7a394399b1f042e347901f61836433..c084c6459a19340330293efb4b557b4b1a01e8e0 100644 (file)
@@ -485,7 +485,7 @@ impl MachineState {
         let location = err.location;
         let err_len = err.len();
 
-        let h = self.heap.h;
+        let h = self.heap.h();
         let mut stub = vec![
             HeapCellValue::NamedStr(2, clause_name!("error"), None),
             HeapCellValue::Addr(Addr::HeapCell(h + 3)),
@@ -512,7 +512,7 @@ impl MachineState {
     }
 
     pub(super) fn throw_exception(&mut self, err: MachineStub) {
-        let h = self.heap.h;
+        let h = self.heap.h();
 
         self.ball.boundary = 0;
         self.ball.stub.truncate(0);
index 0d1aac8b1304d030569a603569d640e34318bfda..44e086b12c7de4a177da6269fde50412fda2cf28 100644 (file)
@@ -6,7 +6,8 @@ use crate::prolog::fixtures::*;
 use crate::prolog::forms::*;
 use crate::prolog::machine::code_repo::CodeRepo;
 use crate::prolog::machine::Ball;
-use crate::prolog::machine::heap::Heap;
+use crate::prolog::machine::heap::*;
+use crate::prolog::machine::raw_block::RawBlockTraits;
 use crate::prolog::instructions::*;
 use crate::prolog::rug::Integer;
 
@@ -350,14 +351,16 @@ pub enum LocalCodePtr {
 }
 
 impl LocalCodePtr {
-    pub fn assign_if_local(&mut self, cp: CodePtr) {
+    pub(crate)
+    fn assign_if_local(&mut self, cp: CodePtr) {
         match cp {
             CodePtr::Local(local) => *self = local,
             _ => {}
         }
     }
 
-    pub fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
+    pub(crate)
+    fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
         match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
             Some(line) => {
                 match line.as_ref() {
@@ -375,8 +378,9 @@ impl LocalCodePtr {
         false
     }
 
-    pub fn as_functor(&self, heap: &mut Heap) -> Addr {
-        let addr = Addr::HeapCell(heap.h);
+    pub(crate)
+    fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
+        let addr = Addr::HeapCell(heap.h());
 
         match self {
             LocalCodePtr::DirEntry(p) => {
index ab7c9b04ccb29944e3d75cc897ae6f89bfc64a88..5eb4dccc41061a482dc30489cc55b737c541eaba 100644 (file)
@@ -20,15 +20,15 @@ use std::mem;
 use std::ops::{Index, IndexMut};
 
 pub struct Ball {
-    pub(super) boundary: usize,   // ball.0
-    pub(super) stub: MachineStub, // ball.1
+    pub(super) boundary: usize,
+    pub(super) stub: Heap,
 }
 
 impl Ball {
     pub(super) fn new() -> Self {
         Ball {
             boundary: 0,
-            stub: MachineStub::new(),
+            stub: Heap::new(),
         }
     }
 
@@ -43,20 +43,18 @@ impl Ball {
 
         Ball {
             boundary,
-            stub: mem::replace(&mut self.stub, vec![]),
+            stub: self.stub.take(),
         }
     }
 
-    pub(super) fn copy_and_align(&self, h: usize) -> MachineStub {
+    pub(super) fn copy_and_align(&self, h: usize) -> Heap {
         let diff = self.boundary as i64 - h as i64;
-        let mut stub = vec![];
-
-        for index in 0..self.stub.len() {
-            let heap_value = self.stub[index].clone();
+        let mut stub = Heap::new();
 
+        for heap_value in self.stub.iter_from(0).cloned() {
             stub.push(match heap_value {
                 HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
-                _ => heap_value,
+                heap_value => heap_value,
             });
         }
 
@@ -91,7 +89,7 @@ impl<'a> IndexMut<usize> for CopyTerm<'a> {
 // the ordinary, heap term copier, used by duplicate_term.
 impl<'a> CopierTarget for CopyTerm<'a> {
     fn threshold(&self) -> usize {
-        self.state.heap.h
+        self.state.heap.h()
     }
 
     fn push(&mut self, hcv: HeapCellValue) {
@@ -115,16 +113,17 @@ pub(super) struct CopyBallTerm<'a> {
     stack: &'a mut Stack,
     heap: &'a mut Heap,
     heap_boundary: usize,
-    stub: &'a mut MachineStub,
+    stub: &'a mut Heap,
 }
 
 impl<'a> CopyBallTerm<'a> {
     pub(super) fn new(
         stack: &'a mut Stack,
         heap: &'a mut Heap,
-        stub: &'a mut MachineStub,
+        stub: &'a mut Heap,
     ) -> Self {
-        let hb = heap.len();
+        let hb = heap.h();
+
         CopyBallTerm {
             stack,
             heap,
@@ -161,7 +160,7 @@ impl<'a> IndexMut<usize> for CopyBallTerm<'a> {
 // the ordinary, heap term copier, used by duplicate_term.
 impl<'a> CopierTarget for CopyBallTerm<'a> {
     fn threshold(&self) -> usize {
-        self.heap_boundary + self.stub.len()
+        self.heap_boundary + self.stub.h()
     }
 
     fn push(&mut self, value: HeapCellValue) {
@@ -253,7 +252,7 @@ pub struct MachineState {
     pub(super) hb: usize,
     pub(super) block: usize, // an offset into the OR stack.
     pub(super) ball: Ball,
-    pub(super) lifted_heap: Vec<HeapCellValue>,
+    pub(super) lifted_heap: Heap,
     pub(super) interms: Vec<Number>, // intermediate numbers.
     pub(super) last_call: bool,
     pub(crate) heap_locs: HeapVarDict,
@@ -268,7 +267,7 @@ impl MachineState {
         let mut iter = addrs.iter();
 
         while let Some(addr) = iter.next() {
-            match addr {                
+            match addr {
                 &Addr::Con(Constant::String(n, ref s))
                     if self.flags.double_quotes.is_chars() => {
                         if s.len() < n {
@@ -278,7 +277,7 @@ impl MachineState {
                         if iter.next().is_some() {
                             return Err(MachineError::type_error(ValidType::Character, addr.clone()));
                         }
-                    }                
+                    }
                 &Addr::Con(Constant::Char(c)) => {
                     chars.push(c);
                 }
@@ -368,7 +367,7 @@ impl MachineState {
             }
         }
 
-        let h = self.heap.h;
+        let h = self.heap.h();
         let stub = MachineError::functor_stub(name.clone(), arity);
         let err = MachineError::module_resolution_error(h, module_name, name, arity);
 
@@ -412,7 +411,7 @@ fn try_in_situ(
         Ok(())
     } else {
         let stub = MachineError::functor_stub(name.clone(), arity);
-        let h = machine_st.heap.h;
+        let h = machine_st.heap.h();
         let key = ExistenceError::Procedure(name, arity);
 
         Err(machine_st.error_form(MachineError::existence_error(h, key), stub))
@@ -455,7 +454,7 @@ pub(crate) trait CallPolicy: Any {
             attr_var_init_bindings_b,
         );
 
-        machine_st.hb = machine_st.heap.h;
+        machine_st.hb = machine_st.heap.h();
         machine_st.p += 1;
 
         Ok(())
@@ -491,7 +490,7 @@ pub(crate) trait CallPolicy: Any {
 
         machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
 
-        machine_st.hb = machine_st.heap.h;
+        machine_st.hb = machine_st.heap.h();
         machine_st.p += offset;
 
         Ok(())
@@ -530,7 +529,7 @@ pub(crate) trait CallPolicy: Any {
         machine_st.stack.truncate(machine_st.b);
         machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
 
-        machine_st.hb = machine_st.heap.h;
+        machine_st.hb = machine_st.heap.h();
         machine_st.p += offset;
 
         Ok(())
@@ -570,7 +569,7 @@ pub(crate) trait CallPolicy: Any {
         machine_st.stack.truncate(machine_st.b);
         machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
 
-        machine_st.hb = machine_st.heap.h;
+        machine_st.hb = machine_st.heap.h();
         machine_st.p += 1;
 
         Ok(())
@@ -716,7 +715,7 @@ pub(crate) trait CallPolicy: Any {
                         machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
                     }
                     Err(e) => {
-                        let h = machine_st.heap.h;
+                        let h = machine_st.heap.h();
                         let stub = MachineError::functor_stub(clause_name!("read"), 1);
                         let err = MachineError::syntax_error(h, e);
                         let err = machine_st.error_form(err, stub);
@@ -967,7 +966,7 @@ impl CWILCallPolicy {
     }
 
     fn increment(&mut self, machine_st: &MachineState) -> CallResult {
-        if self.inference_limit_exceeded || machine_st.ball.stub.len() > 0 {
+        if self.inference_limit_exceeded || machine_st.ball.stub.h() > 0 {
             return Ok(());
         }
 
index a305ab7249a8f60bc51dc1b9cbf3b7c12479618a..e18cee940a48808f5b878ffca3e8ca35d489feed 100644 (file)
@@ -60,7 +60,7 @@ impl MachineState {
             cp: LocalCodePtr::default(),
             attr_var_init: AttrVarInitializer::new(0, 0),
             fail: false,
-            heap: Heap::with_capacity(1024),
+            heap: Heap::new(),
             mode: MachineMode::Write,
             stack: Stack::new(),
             registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
@@ -69,7 +69,7 @@ impl MachineState {
             hb: 0,
             block: 0,
             ball: Ball::new(),
-            lifted_heap: Vec::with_capacity(1024),
+            lifted_heap: Heap::new(),
             interms: vec![Number::default(); 256],
             last_call: false,
             heap_locs: HeapVarDict::new(),
@@ -78,7 +78,7 @@ impl MachineState {
         }
     }
 
-    pub(crate) fn with_capacity(capacity: usize) -> Self {
+    pub(crate) fn with_small_heap() -> Self {
         MachineState {
             s: 0,
             p: CodePtr::default(),
@@ -89,7 +89,7 @@ impl MachineState {
             cp: LocalCodePtr::default(),
             attr_var_init: AttrVarInitializer::new(0, 0),
             fail: false,
-            heap: Heap::with_capacity(capacity),
+            heap: Heap::new(),
             mode: MachineMode::Write,
             stack: Stack::new(),
             registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
@@ -98,7 +98,7 @@ impl MachineState {
             hb: 0,
             block: 0,
             ball: Ball::new(),
-            lifted_heap: Vec::with_capacity(capacity),
+            lifted_heap: Heap::new(),
             interms: vec![Number::default(); 0],
             last_call: false,
             heap_locs: HeapVarDict::new(),
@@ -109,7 +109,7 @@ impl MachineState {
 
     #[allow(dead_code)]
     pub fn print_heap(&self, start: usize) {
-        for h in start .. self.heap.h {
+        for h in start .. self.heap.h() {
             println!("{} : {}", h, self.heap[h]);
         }
     }
@@ -1377,7 +1377,7 @@ impl MachineState {
 
     fn get_char_list(&mut self, offset: usize, s: Rc<String>) {
         if let Some(c) = s[offset ..].chars().next() {
-            let h = self.heap.h;
+            let h = self.heap.h();
 
             self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
             self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(
@@ -1413,7 +1413,7 @@ impl MachineState {
                     addr @ Addr::AttrVar(_)
                   | addr @ Addr::StackCell(..)
                   | addr @ Addr::HeapCell(_) => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
                         self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
@@ -1444,7 +1444,7 @@ impl MachineState {
                         }
                     }
                     Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
                         self.heap
@@ -1481,7 +1481,7 @@ impl MachineState {
                 match self.mode {
                     MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s),
                     MachineMode::Write => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
                         self[reg] = Addr::HeapCell(h);
@@ -1500,7 +1500,7 @@ impl MachineState {
                     }
                     MachineMode::Write => {
                         let addr = self.deref(self[reg].clone());
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         if let Addr::HeapCell(hc) = addr {
                             if hc < h {
@@ -1540,7 +1540,7 @@ impl MachineState {
                 match self.mode {
                     MachineMode::Read => self.s += n,
                     MachineMode::Write => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         for i in h..h + n {
                             self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i)));
@@ -1633,9 +1633,9 @@ impl MachineState {
             &QueryInstruction::PutConstant(_, ref constant, reg) => {
                 self[reg] = Addr::Con(constant.clone())
             }
-            &QueryInstruction::PutList(_, reg) => self[reg] = Addr::Lis(self.heap.h),
+            &QueryInstruction::PutList(_, reg) => self[reg] = Addr::Lis(self.heap.h()),
             &QueryInstruction::PutStructure(ref ct, arity, reg) => {
-                let h = self.heap.h;
+                let h = self.heap.h();
 
                 self.heap
                     .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
@@ -1648,7 +1648,7 @@ impl MachineState {
                 if addr.is_protected(e) {
                     self.registers[arg] = self.store(addr);
                 } else {
-                    let h = self.heap.h;
+                    let h = self.heap.h();
 
                     self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
                     self.bind(Ref::HeapCell(h), addr);
@@ -1666,7 +1666,7 @@ impl MachineState {
                         self.registers[arg] = self[norm].clone();
                     }
                     RegType::Temp(_) => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
                         self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
 
                         self[norm] = Addr::HeapCell(h);
@@ -1679,7 +1679,7 @@ impl MachineState {
             }
             &QueryInstruction::SetLocalValue(reg) => {
                 let addr = self.deref(self[reg].clone());
-                let h = self.heap.h;
+                let h = self.heap.h();
 
                 if let Addr::HeapCell(hc) = addr {
                     if hc < h {
@@ -1693,7 +1693,7 @@ impl MachineState {
                 self.bind(Ref::HeapCell(h), addr);
             }
             &QueryInstruction::SetVariable(reg) => {
-                let h = self.heap.h;
+                let h = self.heap.h();
                 self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
                 self[reg] = Addr::HeapCell(h);
             }
@@ -1702,7 +1702,7 @@ impl MachineState {
                 self.heap.push(HeapCellValue::Addr(heap_val));
             }
             &QueryInstruction::SetVoid(n) => {
-                let h = self.heap.h;
+                let h = self.heap.h();
 
                 for i in h..h + n {
                     self.heap.push(HeapCellValue::Addr(Addr::HeapCell(i)));
@@ -1715,7 +1715,7 @@ impl MachineState {
         self.ball.reset();
 
         let addr = self[temp_v!(1)].clone();
-        self.ball.boundary = self.heap.h;
+        self.ball.boundary = self.heap.h();
 
         copy_term(
             CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.ball.stub),
@@ -2411,16 +2411,16 @@ impl MachineState {
         let spec = fetch_atom_op_spec(name.clone(), spec, op_dir);
 
         let f_a = if name.as_str() == "." && arity == 2 {
-            Addr::Lis(self.heap.h)
+            Addr::Lis(self.heap.h())
         } else {
-            let h = self.heap.h;
+            let h = self.heap.h();
             self.heap
                 .push(HeapCellValue::NamedStr(arity as usize, name, spec));
             Addr::Str(h)
         };
 
         for _ in 0..arity {
-            let h = self.heap.h;
+            let h = self.heap.h();
             self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
         }
 
@@ -2631,7 +2631,7 @@ impl MachineState {
     }
 
     pub(super) fn copy_term(&mut self, attr_var_policy: AttrVarPolicy) {
-        let old_h = self.heap.h;
+        let old_h = self.heap.h();
 
         let a1 = self[temp_v!(1)].clone();
         let a2 = self[temp_v!(2)].clone();
@@ -2904,7 +2904,7 @@ impl MachineState {
                 or_frame.prelude.b = self.b;
                 or_frame.prelude.bp = self.p.local() + 1;
                 or_frame.prelude.tr = self.tr;
-                or_frame.prelude.h  = self.heap.h;
+                or_frame.prelude.h  = self.heap.h();
                 or_frame.prelude.b0 = self.b0;
 
                 or_frame.prelude.attr_var_init_queue_b =
@@ -2918,7 +2918,7 @@ impl MachineState {
                     self.stack.index_or_frame_mut(b)[i-1] = self.registers[i].clone();
                 }
 
-                self.hb = self.heap.h;
+                self.hb = self.heap.h();
                 self.p += offset;
             }
             &IndexedChoiceInstruction::Retry(l) => try_or_fail!(self, call_policy.retry(self, l)),
@@ -2943,7 +2943,7 @@ impl MachineState {
                 or_frame.prelude.b = self.b;
                 or_frame.prelude.bp = self.p.local() + offset;
                 or_frame.prelude.tr = self.tr;
-                or_frame.prelude.h  = self.heap.h;
+                or_frame.prelude.h  = self.heap.h();
                 or_frame.prelude.b0 = self.b0;
                 or_frame.prelude.attr_var_init_queue_b =
                     self.attr_var_init.attr_var_queue.len();
@@ -2956,7 +2956,7 @@ impl MachineState {
                     self.stack.index_or_frame_mut(b)[i-1] = self.registers[i].clone();
                 }
 
-                self.hb = self.heap.h;
+                self.hb = self.heap.h();
                 self.p += 1;
             }
             &ChoiceInstruction::DefaultRetryMeElse(offset) => {
index d2abfef242953906eed1b0d8e15c545f19bae254..e1f0265b003281f369304d272da8fee85175f86b 100644 (file)
@@ -5,7 +5,7 @@ use crate::prolog::clause_types::*;
 use crate::prolog::forms::*;
 use crate::prolog::heap_print::*;
 use crate::prolog::instructions::*;
-use crate::prolog::machine::heap::Heap;
+use crate::prolog::machine::heap::*;
 use crate::prolog::read::*;
 
 mod attributed_variables;
@@ -335,7 +335,7 @@ impl Machine {
     {
         let mut wam = Machine {
             machine_st: MachineState::new(),
-            inner_heap: Heap::with_capacity(256 * 256),
+            inner_heap: Heap::new(),
             policies: MachinePolicies::new(),
             indices: IndexStore::new(),
             code_repo: CodeRepo::new(),
@@ -491,7 +491,7 @@ impl Machine {
     }
 
     fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
-        let h = self.machine_st.heap.h;
+        let h = self.machine_st.heap.h();
 
         let err = MachineError::session_error(h, err);
         let stub = MachineError::functor_stub(key.0, key.1);
@@ -692,7 +692,7 @@ impl Machine {
     }
 
     fn sink_to_snapshot(&mut self) -> MachineState {
-        let mut snapshot = MachineState::with_capacity(0);
+        let mut snapshot = MachineState::with_small_heap();
 
         snapshot.hb = self.machine_st.hb;
         snapshot.e = self.machine_st.e;
@@ -711,7 +711,7 @@ impl Machine {
         snapshot.block = self.machine_st.block;
 
         snapshot.ball = self.machine_st.ball.take();
-        snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]);
+        snapshot.lifted_heap = self.machine_st.lifted_heap.take();
 
         snapshot
     }
@@ -738,7 +738,7 @@ impl Machine {
         self.machine_st.block = snapshot.block;
 
         self.machine_st.ball = snapshot.ball.take();
-        self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
+        self.machine_st.lifted_heap = snapshot.lifted_heap.take();
     }
 
     pub(super) fn run_query(&mut self) {
index 3539425ff8e485226df399f98c26fbf5ac8ea786..b9e7f7edb65939ca3e4152405ef59abb341484fd 100644 (file)
@@ -5,9 +5,13 @@ use std::mem;
 use std::ptr;
 
 pub(crate) trait RawBlockTraits {
-    fn init_size() -> usize;
+    fn init_size() -> usize;    
     fn align() -> usize;
-    fn base_offset(base: *const u8) -> *const u8;
+
+    #[inline]
+    fn base_offset(base: *const u8) -> *const u8 {
+        base
+    }
 }
 
 pub(crate) struct RawBlock<T: RawBlockTraits> {
index 2916b27b4e7d682c77c05ac4f2db93a21d5d180e..9984dfe138ba31cfc439b6ba10ecf9e1add46edf 100644 (file)
@@ -141,6 +141,7 @@ pub struct OrFrame {
 impl Index<usize> for OrFrame {
     type Output = Addr;
 
+    #[inline]
     fn index(&self, index: usize) -> &Self::Output {
         let prelude_offset = prelude_size::<OrFramePrelude>();
         let index_offset = index * mem::size_of::<Addr>();
@@ -155,6 +156,7 @@ impl Index<usize> for OrFrame {
 }
 
 impl IndexMut<usize> for OrFrame {
+    #[inline]
     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
         let prelude_offset = prelude_size::<OrFramePrelude>();
         let index_offset = index * mem::size_of::<Addr>();
index 0fc09b97b063688dff499993d1997d641cd6dfdc..1eb3f912f8de4b157b6386796eb1482a97fa37a3 100644 (file)
@@ -283,7 +283,7 @@ impl MachineState {
                     let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
                     let var_atom = Constant::Atom(var_atom, None);
 
-                    let h = self.heap.h;
+                    let h = self.heap.h();
                     let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
 
                     self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
@@ -307,7 +307,7 @@ impl MachineState {
                 // reset the input stream after an input failure.
                 *current_input_stream = readline::input_stream();
 
-                let h = self.heap.h;
+                let h = self.heap.h();
                 let syntax_error = MachineError::syntax_error(h, err);
                 let stub = MachineError::functor_stub(clause_name!("read_term"), 2);
 
@@ -328,9 +328,13 @@ impl MachineState {
     }
 
     fn copy_findall_solution(&mut self, lh_offset: usize, copy_target: Addr) -> usize {
-        let threshold = self.lifted_heap.len() - lh_offset;
-        let mut copy_ball_term =
-            CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut self.lifted_heap);
+        let threshold = self.lifted_heap.h() - lh_offset;
+        
+        let mut copy_ball_term = CopyBallTerm::new(
+            &mut self.stack,
+            &mut self.heap,
+            &mut self.lifted_heap,
+        );
 
         copy_ball_term.push(HeapCellValue::Addr(Addr::Lis(threshold + 1)));
         copy_ball_term.push(HeapCellValue::Addr(Addr::HeapCell(threshold + 3)));
@@ -356,10 +360,10 @@ impl MachineState {
     {
         match self.store(self.deref(self[temp_v!(1)].clone())) {
             Addr::Con(Constant::Usize(lh_offset)) => {
-                if lh_offset >= self.lifted_heap.len() {
+                if lh_offset >= self.lifted_heap.h() {
                     self.lifted_heap.truncate(lh_offset);
                 } else {
-                    let threshold = self.lifted_heap.len() - lh_offset;
+                    let threshold = self.lifted_heap.h() - lh_offset;
                     self.lifted_heap
                         .push(HeapCellValue::Addr(addr_constr(threshold)));
                 }
@@ -466,7 +470,7 @@ impl MachineState {
                 });
                 let err = ParserError::UnexpectedChar(c, line_num, col_num);
 
-                let h = self.heap.h;
+                let h = self.heap.h();
                 let err = MachineError::syntax_error(h, err);
 
                 return Err(self.error_form(err, stub));
@@ -480,7 +484,7 @@ impl MachineState {
 
         match parser.read_term(composite_op!(&indices.op_dir)) {
             Err(err) => {
-                let h = self.heap.h;
+                let h = self.heap.h();
                 let err = MachineError::syntax_error(h, err);
 
                 return Err(self.error_form(err, stub));
@@ -500,7 +504,7 @@ impl MachineState {
             _ => {
                 let err = ParserError::ParseBigInt(0, 0);
 
-                let h = self.heap.h;
+                let h = self.heap.h();
                 let err = MachineError::syntax_error(h, err);
 
                 return Err(self.error_form(err, stub));
@@ -893,7 +897,7 @@ impl MachineState {
             }
             &SystemClauseType::LiftedHeapLength => {
                 let a1 = self[temp_v!(1)].clone();
-                let lh_len = Addr::Con(Constant::Usize(self.lifted_heap.len()));
+                let lh_len = Addr::Con(Constant::Usize(self.lifted_heap.h()));
 
                 self.unify(a1, lh_len);
             }
@@ -960,7 +964,7 @@ impl MachineState {
 
                 match indices.global_variables.get_mut(&key) {
                     Some((ref mut ball, None)) => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
                         let stub = ball.copy_and_align(h);
 
                         self.heap.extend(stub.into_iter());
@@ -984,7 +988,7 @@ impl MachineState {
 
                 match indices.global_variables.get_mut(&key) {
                     Some((ref mut ball, ref mut offset @ None)) => {
-                        let h = self.heap.h;
+                        let h = self.heap.h();
                         let stub = ball.copy_and_align(h);
 
                         self.heap.extend(stub.into_iter());
@@ -1108,15 +1112,15 @@ impl MachineState {
                         let copy_target = self[temp_v!(2)].clone();
 
                         let old_threshold = self.copy_findall_solution(lh_offset, copy_target);
-                        let new_threshold = self.lifted_heap.len() - lh_offset;
+                        let new_threshold = self.lifted_heap.h() - lh_offset;
 
                         self.lifted_heap[old_threshold] =
                             HeapCellValue::Addr(Addr::HeapCell(new_threshold));
 
-                        for index in old_threshold + 1..self.lifted_heap.len() {
-                            match &mut self.lifted_heap[index] {
+                        for addr in self.lifted_heap.iter_mut_from(old_threshold + 1) {
+                            match addr {
                                 &mut HeapCellValue::Addr(ref mut addr) => {
-                                    *addr -= self.heap.len() + lh_offset
+                                    *addr -= self.heap.h() + lh_offset
                                 }
                                 _ => {}
                             }
@@ -1433,7 +1437,7 @@ impl MachineState {
                     Ok(()) => {}
                     Err(e) => {
                         // 8.14.3.3 l)
-                        let e = MachineError::session_error(self.heap.h, e);
+                        let e = MachineError::session_error(self.heap.h(), e);
                         let stub = MachineError::functor_stub(clause_name!("op"), 3);
                         let permission_error = self.error_form(e, stub);
 
@@ -1464,7 +1468,7 @@ impl MachineState {
                     Addr::AttrVar(h) => h + 1,
                     attr_var @ Addr::HeapCell(_) | attr_var @ Addr::StackCell(..) => {
                         // create an AttrVar in the heap.
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h)));
                         self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1)));
@@ -1545,7 +1549,7 @@ impl MachineState {
                     addrs.push(self.stack.index_and_frame(e)[index].clone());
                 }
 
-                let chunk = Addr::HeapCell(self.heap.h);
+                let chunk = Addr::HeapCell(self.heap.h());
 
                 self.heap.push(HeapCellValue::NamedStr(
                     1 + num_cells,
@@ -1563,27 +1567,34 @@ impl MachineState {
 
                 match self.store(self.deref(lh_offset)) {
                     Addr::Con(Constant::Usize(lh_offset)) => {
-                        if lh_offset >= self.lifted_heap.len() {
+                        if lh_offset >= self.lifted_heap.h() {
                             let solutions = self[temp_v!(2)].clone();
                             let diff = self[temp_v!(3)].clone();
 
                             self.unify(solutions, Addr::Con(Constant::EmptyList));
                             self.unify(diff, Addr::Con(Constant::EmptyList));
                         } else {
-                            let h = self.heap.h;
+                            let h = self.heap.h();
+                            let mut last_index = h;
 
-                            for index in lh_offset..self.lifted_heap.len() {
-                                match self.lifted_heap[index].clone() {
+                            for value in self.lifted_heap.iter_from(lh_offset) {
+                                last_index = self.heap.h();
+                                
+                                match value.clone() {
                                     HeapCellValue::Addr(addr) => {
-                                        self.heap.push(HeapCellValue::Addr(addr + h))
+                                        self.heap.push(HeapCellValue::Addr(addr + h));
+                                    }
+                                    value => {
+                                        self.heap.push(value);
                                     }
-                                    value => self.heap.push(value),
                                 }
                             }
 
-                            if let Some(HeapCellValue::Addr(addr)) = self.heap.last().cloned() {
-                                let diff = self[temp_v!(3)].clone();
-                                self.unify(diff, addr);
+                            if last_index < self.heap.h() {
+                                if let HeapCellValue::Addr(addr) = self.heap[last_index].clone() {
+                                    let diff = self[temp_v!(3)].clone();
+                                    self.unify(diff, addr);
+                                }
                             }
 
                             self.lifted_heap.truncate(lh_offset);
@@ -1600,18 +1611,20 @@ impl MachineState {
 
                 match self.store(self.deref(lh_offset)) {
                     Addr::Con(Constant::Usize(lh_offset)) => {
-                        if lh_offset >= self.lifted_heap.len() {
+                        if lh_offset >= self.lifted_heap.h() {
                             let solutions = self[temp_v!(2)].clone();
                             self.unify(solutions, Addr::Con(Constant::EmptyList));
                         } else {
-                            let h = self.heap.h;
+                            let h = self.heap.h();
 
-                            for index in lh_offset..self.lifted_heap.len() {
-                                match self.lifted_heap[index].clone() {
+                            for addr in self.lifted_heap.iter_from(lh_offset).cloned() {
+                                match addr {
                                     HeapCellValue::Addr(addr) => {
                                         self.heap.push(HeapCellValue::Addr(addr + h))
                                     }
-                                    value => self.heap.push(value),
+                                    value => {
+                                        self.heap.push(value);
+                                    }
                                 }
                             }
 
@@ -1825,7 +1838,7 @@ impl MachineState {
 
                 let value = self[temp_v!(2)].clone();
                 let mut ball = Ball::new();
-                let h = self.heap.h;
+                let h = self.heap.h();
 
                 ball.boundary = h;
                 copy_term(
@@ -2004,11 +2017,11 @@ impl MachineState {
             &SystemClauseType::Fail => self.fail = true,
             &SystemClauseType::GetBall => {
                 let addr = self.store(self.deref(self[temp_v!(1)].clone()));
-                let h = self.heap.h;
+                let h = self.heap.h();
 
-                if self.ball.stub.len() > 0 {
+                if self.ball.stub.h() > 0 {
                     let stub = self.ball.copy_and_align(h);
-                    self.heap.append(stub);
+                    self.heap.extend(stub.into_iter());
                 } else {
                     self.fail = true;
                     return Ok(());
@@ -2168,7 +2181,7 @@ impl MachineState {
             &SystemClauseType::ResetContinuationMarker => {
                 self[temp_v!(3)] = Addr::Con(Constant::Atom(clause_name!("none"), None));
 
-                let h = self.heap.h;
+                let h = self.heap.h();
                 self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
 
                 self[temp_v!(4)] = Addr::HeapCell(h);
@@ -2215,7 +2228,7 @@ impl MachineState {
                 let value = self[temp_v!(2)].clone();
                 let mut ball = Ball::new();
 
-                ball.boundary = self.heap.h;
+                ball.boundary = self.heap.h();
                 copy_term(
                     CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
                     value,
@@ -2234,7 +2247,7 @@ impl MachineState {
 
                 let value = self[temp_v!(2)].clone();
                 let mut ball = Ball::new();
-                let h = self.heap.h;
+                let h = self.heap.h();
 
                 ball.boundary = h;
                 copy_term(
@@ -2324,7 +2337,7 @@ impl MachineState {
                         } else {
                             let arity = arity.to_usize().unwrap();
                             let stub = MachineError::functor_stub(name.clone(), arity);
-                            let h = self.heap.h;
+                            let h = self.heap.h();
 
                             let err = MachineError::existence_error(
                                 h,
@@ -2339,7 +2352,7 @@ impl MachineState {
                     None => {
                         let arity = arity.to_usize().unwrap();
                         let stub = MachineError::functor_stub(name.clone(), arity);
-                        let h = self.heap.h;
+                        let h = self.heap.h();
 
                         let err = MachineError::existence_error(
                             h,
@@ -2352,7 +2365,7 @@ impl MachineState {
                     }
                 };
 
-                let mut h = self.heap.h;
+                let mut h = self.heap.h();
                 let mut functors = vec![];
 
                 walk_code(
index 9c91e55554e7ee4ed5645b19d61770ddd77a4893..c14259557a5a4787be6a1a71f7594f69c82cf1ee 100644 (file)
@@ -369,7 +369,7 @@ impl MachineState {
         hook: CompileTimeHook,
     ) -> Option<String> {
         let term_write_result = write_term_to_heap(term, self);
-        let h = self.heap.h;
+        let h = self.heap.h();
 
         self[temp_v!(1)] = Addr::HeapCell(term_write_result.heap_loc);
         self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
index ee753b4af2303d54b64768ce3cba04a320a77326..d45a74141fd29d6567e900b0b645dc7b36d7b7fe 100644 (file)
@@ -120,7 +120,7 @@ impl MachineState {
 }
 
 fn push_stub_addr(machine_st: &mut MachineState) {
-    let h = machine_st.heap.h;
+    let h = machine_st.heap.h();
     machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
 }
 
@@ -145,13 +145,13 @@ pub struct TermWriteResult {
 }
 
 pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
-    let heap_loc = machine_st.heap.h;
+    let heap_loc = machine_st.heap.h();
 
     let mut queue = SubtermDeque::new();
     let mut var_dict = HeapVarDict::new();
 
     for term in breadth_first_iter(term, true) {
-        let h = machine_st.heap.h;
+        let h = machine_st.heap.h();
 
         match &term {
             &TermRef::Cons(lvl, ..) => {