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);
-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) => {
}
}
-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)
+ }
}
}
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)),
}
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);
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;
}
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() {
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) => {
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(),
}
}
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,
});
}
// 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) {
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,
// 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) {
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,
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 {
if iter.next().is_some() {
return Err(MachineError::type_error(ValidType::Character, addr.clone()));
}
- }
+ }
&Addr::Con(Constant::Char(c)) => {
chars.push(c);
}
}
}
- 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);
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))
attr_var_init_bindings_b,
);
- machine_st.hb = machine_st.heap.h;
+ machine_st.hb = machine_st.heap.h();
machine_st.p += 1;
Ok(())
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(())
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(())
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(())
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);
}
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(());
}
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.
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(),
}
}
- pub(crate) fn with_capacity(capacity: usize) -> Self {
+ pub(crate) fn with_small_heap() -> Self {
MachineState {
s: 0,
p: CodePtr::default(),
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.
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(),
#[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]);
}
}
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(
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));
}
}
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
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);
}
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 {
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)));
&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()));
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);
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);
}
&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 {
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);
}
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)));
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),
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)));
}
}
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();
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 =
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)),
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();
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) => {
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;
{
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(),
}
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);
}
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;
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
}
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) {
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> {
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>();
}
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>();
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));
// 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);
}
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)));
{
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)));
}
});
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));
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));
_ => {
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));
}
&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);
}
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());
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());
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
}
_ => {}
}
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);
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)));
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,
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);
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);
+ }
}
}
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(
&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(());
&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);
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,
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(
} 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,
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,
}
};
- let mut h = self.heap.h;
+ let mut h = self.heap.h();
let mut functors = vec![];
walk_code(
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)));
}
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)));
}
}
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, ..) => {