use raw_block.rs for the heap backend

This commit is contained in:
Mark Thom
2020-02-16 16:30:36 -07:00
parent 5f51e264f2
commit 8902bcb5ab
12 changed files with 353 additions and 170 deletions

View 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);

View File

@@ -1,99 +1,252 @@
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 struct Heap {
heap: Vec<HeapCellValue>,
pub h: usize,
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>()
}
}
impl Heap {
pub fn with_capacity(cap: usize) -> Self {
Heap {
heap: Vec::with_capacity(cap),
h: 0,
pub(crate) struct HeapTemplate<T: RawBlockTraits> {
buf: RawBlock<T>,
_marker: PhantomData<HeapCellValue>,
}
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
}
}
}
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 }
}
}
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>();
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(crate)
fn new() -> Self {
HeapTemplate { buf: RawBlock::new(), _marker: PhantomData }
}
#[inline]
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 push(&mut self, val: HeapCellValue) {
self.heap.push(val);
self.h += 1;
}
#[inline]
pub(crate) fn take(&mut self) -> Self {
let h = self.h;
self.h = 0;
Heap {
heap: mem::replace(&mut self.heap, vec![]),
h,
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 fn truncate(&mut self, h: usize) {
self.h = h;
self.heap.truncate(h);
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 _;
}
#[inline]
pub fn last(&self) -> Option<&HeapCellValue> {
self.heap.last()
pub(crate)
fn h(&self) -> usize {
(self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
}
#[inline]
pub fn len(&self) -> usize {
self.heap.len()
pub(crate)
fn append(&mut self, vals: Vec<HeapCellValue>) {
for val in vals {
self.push(val);
}
}
pub fn append(&mut self, vals: Vec<HeapCellValue>) {
let n = vals.len();
self.heap.extend(vals.into_iter());
self.h += n;
pub(crate)
fn clear(&mut self) {
if !self.buf.base.is_null() {
self.truncate(0);
self.buf.top = self.buf.base;
}
}
pub fn clear(&mut self) {
self.heap.clear();
self.h = 0;
}
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)
}
}
}

View 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);

View 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) => {

View 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(());
}

View 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) => {

View 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) {

View 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> {

View 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>();

View 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(

View 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)));