]> Repositorios git - scryer-prolog.git/commitdiff
introduce InlineTermStream to avoid arena allocations during call_inline (#1576)
authorMark Thom <[email protected]>
Tue, 8 Nov 2022 22:55:22 +0000 (23:55 +0100)
committerMark Thom <[email protected]>
Tue, 8 Nov 2022 23:01:01 +0000 (00:01 +0100)
src/machine/compile.rs
src/machine/loader.rs
src/machine/term_stream.rs

index 7684755fb27937d5809be28aee332f76d93045b9..d7f2492c80d2ce7877b74a90272cc7ea9b47a1b0 100644 (file)
@@ -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)?;
index 3495e5b328bf9c0830db1856b9fbbb9c77506780..616fe7ee207226b9e4462b28441d310e0bb2ac6e 100644 (file)
@@ -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(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;
index a1d38271033e1b997a61a2998672d98fe309aa20..bb92c8d4f8e8c19f10a3718d20e93b4274883187 100644 (file)
@@ -119,3 +119,21 @@ impl TermStream for LiveTermStream {
         &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
+    }
+}
+