flatten the instruction dispatch loop

This commit is contained in:
Mark Thom
2021-12-19 18:57:57 -07:00
parent 3db86f1e25
commit 955e1799c8
52 changed files with 14247 additions and 10021 deletions

View File

@@ -2,30 +2,22 @@ use crate::parser::ast::*;
use crate::arena::*;
use crate::atom_table::*;
use crate::clause_types::*;
use crate::fixtures::*;
use crate::forms::*;
use crate::instructions::*;
use crate::machine::*;
use crate::machine::heap::*;
use crate::machine::loader::*;
use crate::machine::machine_errors::MachineStub;
use crate::machine::machine_state::*;
use crate::machine::streams::Stream;
use fxhash::FxBuildHasher;
use indexmap::IndexMap;
use std::cell::Cell;
use std::cmp::Ordering;
use std::collections::BTreeSet;
use std::ops::{Add, AddAssign, Deref, Sub, SubAssign};
use std::ops::Deref;
use std::rc::Rc;
// these statics store the locations of one-off control instructions
// in the code vector.
pub static HALT_CODE: usize = 0;
use crate::types::*;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct OrderedOpDirKey(pub(crate) Atom, pub(crate) Fixity);
@@ -134,6 +126,7 @@ impl Default for CodeIndex {
}
}
/*
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum REPLCodePtr {
AddDiscontiguousPredicate,
@@ -174,158 +167,30 @@ pub enum REPLCodePtr {
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CodePtr {
BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
Local(LocalCodePtr),
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
BuiltInClause(BuiltInClauseType, usize), // local is the successor call.
CallN(usize, usize, bool), // arity, local, last call.
Local(usize),
REPL(REPLCodePtr, usize), // the REPL code, the return pointer.
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
}
impl CodePtr {
pub(crate) fn local(&self) -> LocalCodePtr {
pub(crate) fn local(&self) -> usize {
match self {
&CodePtr::BuiltInClause(_, ref local)
| &CodePtr::CallN(_, ref local, _)
| &CodePtr::Local(ref local) => local.clone(),
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
&CodePtr::BuiltInClause(_, ref local) |
&CodePtr::CallN(_, ref local, _) |
&CodePtr::Local(ref local) => *local,
&CodePtr::VerifyAttrInterrupt(p) => p,
&CodePtr::REPL(_, p) => p,
}
}
#[inline]
pub(crate) fn is_halt(&self) -> bool {
if let CodePtr::Local(LocalCodePtr::Halt) = self {
true
} else {
false
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum LocalCodePtr {
DirEntry(usize), // offset
Halt,
// IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
// TopLevel(usize, usize), // chunk_num, offset
}
impl Machine {
pub(crate) fn is_reset_cont_marker(&self, p: LocalCodePtr) -> bool {
match self.code_repo.lookup_instr(&self.machine_st, &CodePtr::Local(p)) {
Some(line) => match line.as_ref(&self.code_repo.code) {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
return true;
}
}
_ => {}
},
None => {}
}
false
}
}
impl LocalCodePtr {
pub fn assign_if_local(&mut self, cp: CodePtr) {
match cp {
CodePtr::Local(local) => *self = local,
pub fn assign_if_local(&self, cp: &mut usize) {
match self {
CodePtr::Local(local) => *cp = *local,
_ => {}
}
}
#[inline]
pub fn abs_loc(&self) -> usize {
match self {
LocalCodePtr::DirEntry(ref p) => *p,
// LocalCodePtr::IndexingBuf(ref p, ..) => *p,
LocalCodePtr::Halt => unreachable!(),
}
}
pub(crate) fn as_functor(&self) -> MachineStub {
match self {
LocalCodePtr::DirEntry(p) => {
functor!(atom!("dir_entry"), [fixnum(*p)])
}
LocalCodePtr::Halt => {
functor!(atom!("halt"))
}
/*
LocalCodePtr::IndexingBuf(p, o, i) => {
functor!(
atom!("indexed_buf"),
[fixnum(*p), fixnum(*o), fixnum(*i)]
)
}
*/
}
}
}
impl Default for CodePtr {
#[inline]
fn default() -> Self {
CodePtr::Local(LocalCodePtr::default())
}
}
impl Default for LocalCodePtr {
#[inline]
fn default() -> Self {
LocalCodePtr::DirEntry(0)
}
}
impl Add<usize> for LocalCodePtr {
type Output = LocalCodePtr;
#[inline]
fn add(self, rhs: usize) -> Self::Output {
match self {
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
LocalCodePtr::Halt => unreachable!(),
// LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
}
}
}
impl Sub<usize> for LocalCodePtr {
type Output = Option<LocalCodePtr>;
#[inline]
fn sub(self, rhs: usize) -> Self::Output {
match self {
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
LocalCodePtr::Halt => unreachable!(),
// LocalCodePtr::IndexingBuf(p, o, i) => i
// .checked_sub(rhs)
// .map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
}
}
}
impl SubAssign<usize> for LocalCodePtr {
#[inline]
fn sub_assign(&mut self, rhs: usize) {
match self {
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
LocalCodePtr::Halt => unreachable!() // | LocalCodePtr::IndexingBuf(..) => unreachable!(),
}
}
}
impl AddAssign<usize> for LocalCodePtr {
#[inline]
fn add_assign(&mut self, rhs: usize) {
match self {
&mut LocalCodePtr::DirEntry(ref mut i) => *i += rhs,
// | &mut LocalCodePtr::IndexingBuf(_, _, ref mut i) => *i += rhs,
&mut LocalCodePtr::Halt => unreachable!(),
}
}
}
impl Add<usize> for CodePtr {
@@ -333,7 +198,9 @@ impl Add<usize> for CodePtr {
fn add(self, rhs: usize) -> Self::Output {
match self {
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => p,
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
p
}
CodePtr::Local(local) => CodePtr::Local(local + rhs),
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
CodePtr::Local(local + rhs)
@@ -362,20 +229,30 @@ impl SubAssign<usize> for CodePtr {
}
}
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue>;
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData>;
impl Default for CodePtr {
#[inline]
fn default() -> Self {
CodePtr::Local(0)
}
}
*/
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>)>;
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue, FxBuildHasher>;
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>;
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream>;
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;
pub(crate) type StreamAliasDir = IndexMap<Atom, Stream, FxBuildHasher>;
pub(crate) type StreamDir = BTreeSet<Stream>;
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>>;
pub(crate) type MetaPredicateDir = IndexMap<PredicateKey, Vec<MetaSpec>, FxBuildHasher>;
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton>;
pub(crate) type ExtensiblePredicates = IndexMap<PredicateKey, PredicateSkeleton, FxBuildHasher>;
pub(crate) type LocalExtensiblePredicates =
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton>;
IndexMap<(CompilationTarget, PredicateKey), LocalPredicateSkeleton, FxBuildHasher>;
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex, FxBuildHasher>;
#[derive(Debug)]
pub struct IndexStore {
@@ -504,14 +381,14 @@ impl IndexStore {
) -> Option<CodeIndex> {
if module == atom!("user") {
match ClauseType::from(name, arity) {
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
ClauseType::Named(arity, name, _) => self.code_dir.get(&(name, arity)).cloned(),
_ => None,
}
} else {
self.modules
.get(&module)
.and_then(|module| match ClauseType::from(name, arity) {
ClauseType::Named(name, arity, _) => {
ClauseType::Named(arity, name, _) => {
module.code_dir.get(&(name, arity)).cloned()
}
_ => None,
@@ -561,8 +438,10 @@ impl IndexStore {
#[inline]
pub(super) fn new() -> Self {
index_store!(CodeDir::new(), default_op_dir(), ModuleDir::new())
index_store!(
CodeDir::with_hasher(FxBuildHasher::default()),
default_op_dir(),
ModuleDir::with_hasher(FxBuildHasher::default())
)
}
}
pub(crate) type CodeDir = IndexMap<PredicateKey, CodeIndex>;