introduce InlineTermStream to avoid arena allocations during call_inline (#1576)
This commit is contained in:
@@ -2428,9 +2428,9 @@ impl Machine {
|
|||||||
module_name: HeapCellValue,
|
module_name: HeapCellValue,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new(
|
let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
|
||||||
self,
|
self,
|
||||||
LiveTermStream::new(ListingSource::User),
|
InlineTermStream {},
|
||||||
);
|
);
|
||||||
|
|
||||||
let module_name = if module_name.get_tag() == HeapCellValueTag::Atom {
|
let module_name = if module_name.get_tag() == HeapCellValueTag::Atom {
|
||||||
@@ -2448,9 +2448,9 @@ impl Machine {
|
|||||||
vars: &[Term],
|
vars: &[Term],
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let mut compile = || {
|
let mut compile = || {
|
||||||
let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new(
|
let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
|
||||||
self,
|
self,
|
||||||
LiveTermStream::new(ListingSource::User),
|
InlineTermStream {},
|
||||||
);
|
);
|
||||||
|
|
||||||
let term = loader.read_term_from_heap(term_loc)?;
|
let term = loader.read_term_from_heap(term_loc)?;
|
||||||
|
|||||||
@@ -390,6 +390,64 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InlineLoadState<'a> {
|
||||||
|
machine_st: &'a mut MachineState,
|
||||||
|
pub payload: LoadStatePayload<InlineTermStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for InlineLoadState<'a> {
|
||||||
|
type Target = LoadStatePayload<InlineTermStream>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DerefMut for InlineLoadState<'a> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.payload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LoadState<'a> for InlineLoadState<'a> {
|
||||||
|
type TS = InlineTermStream;
|
||||||
|
type LoaderFieldType = InlineLoadState<'a>;
|
||||||
|
type Evacuable = ();
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn new(machine_st: &'a mut MachineState, payload: LoadStatePayload<Self::TS>) -> Self::LoaderFieldType {
|
||||||
|
InlineLoadState { machine_st, payload }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evacuate(_loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn should_drop_load_state(_loader: &Loader<'a, Self>) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn reset_machine(_loader: &mut Loader<'a, Self>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn machine_st(load_state: &mut Self::LoaderFieldType) -> &mut MachineState {
|
||||||
|
&mut load_state.machine_st
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn err_on_builtin_overwrite(
|
||||||
|
_loader: &Loader<'a, Self>,
|
||||||
|
_key: PredicateKey,
|
||||||
|
) -> Result<(), SessionError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Loader<'a, LS: LoadState<'a>> {
|
pub struct Loader<'a, LS: LoadState<'a>> {
|
||||||
pub(super) payload: LS::LoaderFieldType,
|
pub(super) payload: LS::LoaderFieldType,
|
||||||
pub(super) wam_prelude: MachinePreludeView<'a>,
|
pub(super) wam_prelude: MachinePreludeView<'a>,
|
||||||
@@ -2389,21 +2447,15 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn builtin_property(&mut self) {
|
pub(crate) fn builtin_property(&mut self) {
|
||||||
let key = self
|
let (name, arity) = self
|
||||||
.machine_st
|
.machine_st
|
||||||
.read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
|
.read_predicate_key(self.machine_st.registers[1], self.machine_st.registers[2]);
|
||||||
|
|
||||||
match ClauseType::from(key.0, key.1, &mut self.machine_st.arena) {
|
if !ClauseType::is_inbuilt(name, arity) { // ClauseType::from(key.0, key.1, &mut self.machine_st.arena) {
|
||||||
ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => {
|
if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) {
|
||||||
|
self.machine_st.fail = !module.code_dir.contains_key(&(name, arity));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClauseType::Named(arity, name, _) => {
|
|
||||||
if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) {
|
|
||||||
self.machine_st.fail = !module.code_dir.contains_key(&(name, arity));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.fail = true;
|
self.machine_st.fail = true;
|
||||||
|
|||||||
@@ -119,3 +119,21 @@ impl TermStream for LiveTermStream {
|
|||||||
&self.listing_src
|
&self.listing_src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InlineTermStream {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermStream for InlineTermStream {
|
||||||
|
fn next(&mut self, _: &CompositeOpDir) -> Result<Term, CompilationError> {
|
||||||
|
Err(CompilationError::from(ParserError::UnexpectedEOF))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eof(&mut self) -> Result<bool, CompilationError> {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn listing_src(&self) -> &ListingSource {
|
||||||
|
&ListingSource::User
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user