From: Mark Thom Date: Tue, 8 Nov 2022 22:55:22 +0000 (+0100) Subject: introduce InlineTermStream to avoid arena allocations during call_inline (#1576) X-Git-Tag: v0.9.1^2~3 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=9366a48d6d2772ce47cf0d7fed754194cbb1dafb;p=scryer-prolog.git introduce InlineTermStream to avoid arena allocations during call_inline (#1576) --- diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 7684755f..d7f2492c 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -2428,9 +2428,9 @@ impl Machine { module_name: HeapCellValue, key: PredicateKey, ) -> CodeIndex { - let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new( + let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new( self, - LiveTermStream::new(ListingSource::User), + InlineTermStream {}, ); let module_name = if module_name.get_tag() == HeapCellValueTag::Atom { @@ -2448,9 +2448,9 @@ impl Machine { vars: &[Term], ) -> Result<(), SessionError> { let mut compile = || { - let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> = Loader::new( + let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new( self, - LiveTermStream::new(ListingSource::User), + InlineTermStream {}, ); let term = loader.read_term_from_heap(term_loc)?; diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 3495e5b3..616fe7ee 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -390,6 +390,64 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> { } } +pub struct InlineLoadState<'a> { + machine_st: &'a mut MachineState, + pub payload: LoadStatePayload, +} + +impl<'a> Deref for InlineLoadState<'a> { + type Target = LoadStatePayload; + + #[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::LoaderFieldType { + InlineLoadState { machine_st, payload } + } + + fn evacuate(_loader: Loader<'a, Self>) -> Result { + 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(super) payload: LS::LoaderFieldType, pub(super) wam_prelude: MachinePreludeView<'a>, @@ -2389,21 +2447,15 @@ impl Machine { } pub(crate) fn builtin_property(&mut self) { - let key = self + let (name, arity) = self .machine_st .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) { - ClauseType::BuiltIn(_) | ClauseType::Inlined(..) | ClauseType::CallN(_) => { + if !ClauseType::is_inbuilt(name, arity) { // ClauseType::from(key.0, key.1, &mut self.machine_st.arena) { + if let Some(module) = self.indices.modules.get(&(atom!("builtins"))) { + self.machine_st.fail = !module.code_dir.contains_key(&(name, arity)); 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; diff --git a/src/machine/term_stream.rs b/src/machine/term_stream.rs index a1d38271..bb92c8d4 100644 --- a/src/machine/term_stream.rs +++ b/src/machine/term_stream.rs @@ -119,3 +119,21 @@ impl TermStream for LiveTermStream { &self.listing_src } } + +pub struct InlineTermStream { +} + +impl TermStream for InlineTermStream { + fn next(&mut self, _: &CompositeOpDir) -> Result { + Err(CompilationError::from(ParserError::UnexpectedEOF)) + } + + fn eof(&mut self) -> Result { + Ok(true) + } + + fn listing_src(&self) -> &ListingSource { + &ListingSource::User + } +} +