add global_count inference counter that is always incremented (#2009)

This commit is contained in:
Mark
2023-11-20 16:24:31 -07:00
parent 1e5bb2d3da
commit 54166b91eb
6 changed files with 47 additions and 34 deletions

4
Cargo.lock generated
View File

@@ -1599,9 +1599,9 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.16" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]

View File

@@ -329,6 +329,8 @@ enum SystemClauseType {
InstallSCCCleaner, InstallSCCCleaner,
#[strum_discriminants(strum(props(Arity = "3", Name = "$install_inference_counter")))] #[strum_discriminants(strum(props(Arity = "3", Name = "$install_inference_counter")))]
InstallInferenceCounter, InstallInferenceCounter,
#[strum_discriminants(strum(props(Arity = "1", Name = "$inference_count")))]
InferenceCount,
#[strum_discriminants(strum(props(Arity = "1", Name = "$lh_length")))] #[strum_discriminants(strum(props(Arity = "1", Name = "$lh_length")))]
LiftedHeapLength, LiftedHeapLength,
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_library_as_stream")))] #[strum_discriminants(strum(props(Arity = "3", Name = "$load_library_as_stream")))]
@@ -1720,6 +1722,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::CallHeadIsDynamic | &Instruction::CallHeadIsDynamic |
&Instruction::CallInstallSCCCleaner | &Instruction::CallInstallSCCCleaner |
&Instruction::CallInstallInferenceCounter | &Instruction::CallInstallInferenceCounter |
&Instruction::CallInferenceCount |
&Instruction::CallLiftedHeapLength | &Instruction::CallLiftedHeapLength |
&Instruction::CallLoadLibraryAsStream | &Instruction::CallLoadLibraryAsStream |
&Instruction::CallModuleExists | &Instruction::CallModuleExists |
@@ -1954,6 +1957,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::ExecuteHeadIsDynamic | &Instruction::ExecuteHeadIsDynamic |
&Instruction::ExecuteInstallSCCCleaner | &Instruction::ExecuteInstallSCCCleaner |
&Instruction::ExecuteInstallInferenceCounter | &Instruction::ExecuteInstallInferenceCounter |
&Instruction::ExecuteInferenceCount |
&Instruction::ExecuteLiftedHeapLength | &Instruction::ExecuteLiftedHeapLength |
&Instruction::ExecuteLoadLibraryAsStream | &Instruction::ExecuteLoadLibraryAsStream |
&Instruction::ExecuteModuleExists | &Instruction::ExecuteModuleExists |

View File

@@ -36,7 +36,7 @@ macro_rules! try_or_throw {
macro_rules! increment_call_count { macro_rules! increment_call_count {
($s:expr) => {{ ($s:expr) => {{
if !($s.increment_call_count_fn)(&mut $s) { if !$s.increment_call_count() {
$s.backtrack(); $s.backtrack();
continue; continue;
} }
@@ -3675,6 +3675,16 @@ impl Machine {
try_or_throw!(self.machine_st, self.install_inference_counter()); try_or_throw!(self.machine_st, self.install_inference_counter());
step_or_fail!(self, self.machine_st.p = self.machine_st.cp); step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
} }
&Instruction::CallInferenceCount => {
let global_count = self.machine_st.cwil.global_count.clone();
self.inference_count(self.machine_st.registers[1], global_count);
step_or_fail!(self, self.machine_st.p += 1);
}
&Instruction::ExecuteInferenceCount => {
let global_count = self.machine_st.cwil.global_count.clone();
self.inference_count(self.machine_st.registers[1], global_count);
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
}
&Instruction::CallLiftedHeapLength => { &Instruction::CallLiftedHeapLength => {
self.lifted_heap_length(); self.lifted_heap_length();
step_or_fail!(self, self.machine_st.p += 1); step_or_fail!(self, self.machine_st.p += 1);

View File

@@ -96,7 +96,6 @@ pub struct MachineState {
pub(crate) unify_fn: fn(&mut MachineState), pub(crate) unify_fn: fn(&mut MachineState),
pub(crate) bind_fn: fn(&mut MachineState, Ref, HeapCellValue), pub(crate) bind_fn: fn(&mut MachineState, Ref, HeapCellValue),
pub(crate) run_cleaners_fn: fn(&mut Machine) -> bool, pub(crate) run_cleaners_fn: fn(&mut Machine) -> bool,
pub(crate) increment_call_count_fn: fn(&mut MachineState) -> bool,
} }
impl fmt::Debug for MachineState { impl fmt::Debug for MachineState {
@@ -417,15 +416,17 @@ impl MachineState {
return true; return true;
} }
self.cwil.global_count += 1;
if let Some(&(ref limit, block)) = self.cwil.limits.last() { if let Some(&(ref limit, block)) = self.cwil.limits.last() {
if self.cwil.count == *limit { if self.cwil.local_count == *limit {
self.cwil.inference_limit_exceeded = true; self.cwil.inference_limit_exceeded = true;
self.block = block; self.block = block;
self.unwind_stack(); self.unwind_stack();
return false; return false;
} else { } else {
self.cwil.count += 1; self.cwil.local_count += 1;
} }
} }
@@ -967,7 +968,8 @@ impl MachineState {
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct CWIL { pub(crate) struct CWIL {
count: Integer, local_count: Integer,
pub(crate) global_count: Integer,
limits: Vec<(Integer, usize)>, limits: Vec<(Integer, usize)>,
pub(crate) inference_limit_exceeded: bool, pub(crate) inference_limit_exceeded: bool,
} }
@@ -975,22 +977,22 @@ pub(crate) struct CWIL {
impl CWIL { impl CWIL {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
CWIL { CWIL {
count: Integer::from(0), local_count: Integer::from(0),
global_count: Integer::from(0),
limits: vec![], limits: vec![],
inference_limit_exceeded: false, inference_limit_exceeded: false,
} }
} }
pub(crate) fn add_limit(&mut self, limit: usize, block: usize) -> &Integer { pub(crate) fn add_limit(&mut self, mut limit: Integer, block: usize) -> &Integer {
let mut limit = Integer::from(limit); limit += &self.local_count;
limit += &self.count;
match self.limits.last() { match self.limits.last() {
Some((ref inner_limit, _)) if *inner_limit <= limit => {} Some((ref inner_limit, _)) if *inner_limit <= limit => {}
_ => self.limits.push((limit, block)), _ => self.limits.push((limit, block)),
}; }
&self.count &self.local_count
} }
#[inline(always)] #[inline(always)]
@@ -1001,12 +1003,12 @@ impl CWIL {
} }
} }
&self.count &self.local_count
} }
#[inline(always)] #[inline(always)]
pub(crate) fn reset(&mut self) { pub(crate) fn reset(&mut self) {
self.count = Integer::from(0); self.local_count = Integer::from(0);
self.limits.clear(); self.limits.clear();
self.inference_limit_exceeded = false; self.inference_limit_exceeded = false;
} }

View File

@@ -60,7 +60,6 @@ impl MachineState {
unify_fn: MachineState::unify, unify_fn: MachineState::unify,
bind_fn: MachineState::bind, bind_fn: MachineState::bind,
run_cleaners_fn: |_| false, run_cleaners_fn: |_| false,
increment_call_count_fn: |_| true,
} }
} }

View File

@@ -1,8 +1,7 @@
use crate::parser::ast::*; use crate::parser::ast::*;
use crate::parser::parser::*; use crate::parser::parser::*;
use dashu::integer::Sign; use dashu::integer::{Sign, UBig};
use dashu::integer::UBig;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use num_order::NumOrd; use num_order::NumOrd;
@@ -5516,11 +5515,8 @@ impl Machine {
let a2 = self.deref_register(2); let a2 = self.deref_register(2);
let n = match Number::try_from(a2) { let n = match Number::try_from(a2) {
Ok(Number::Fixnum(bp)) => bp.get_num() as usize, Ok(Number::Fixnum(bp)) => Integer::from(bp.get_num() as usize),
Ok(Number::Integer(n)) => { Ok(Number::Integer(n)) => (*n).clone(),
let value: usize = (&*n).try_into().unwrap();
value
}
_ => { _ => {
let stub = functor_stub(atom!("call_with_inference_limit"), 3); let stub = functor_stub(atom!("call_with_inference_limit"), 3);
@@ -5531,21 +5527,24 @@ impl Machine {
let bp = cell_as_fixnum!(a1).get_num() as usize; let bp = cell_as_fixnum!(a1).get_num() as usize;
let a3 = self.deref_register(3); let a3 = self.deref_register(3);
let count = self.machine_st.cwil.add_limit(n, bp);
let result = count.try_into(); let count = self.machine_st.cwil.add_limit(n, bp).clone();
if let Ok(value) = result { self.inference_count(a3, count);
self.machine_st.unify_fixnum(Fixnum::build_with(value), a3);
} else {
let count = arena_alloc!(count.clone(), &mut self.machine_st.arena);
self.machine_st.unify_big_int(count, a3);
}
self.machine_st.increment_call_count_fn = MachineState::increment_call_count;
Ok(()) Ok(())
} }
#[inline(always)]
pub(crate) fn inference_count(&mut self, count_var: HeapCellValue, count: Integer) {
if let Some(value) = <&Integer as TryInto<i64>>::try_into(&count).ok() {
self.machine_st
.unify_fixnum(Fixnum::build_with(value), count_var);
} else {
let count = arena_alloc!(count, &mut self.machine_st.arena);
self.machine_st.unify_big_int(count, count_var);
}
}
#[inline(always)] #[inline(always)]
pub(crate) fn module_exists(&mut self) { pub(crate) fn module_exists(&mut self) {
let module = self.deref_register(1); let module = self.deref_register(1);
@@ -5671,7 +5670,6 @@ impl Machine {
if bp == self.machine_st.b && self.machine_st.cwil.is_empty() { if bp == self.machine_st.b && self.machine_st.cwil.is_empty() {
self.machine_st.cwil.reset(); self.machine_st.cwil.reset();
self.machine_st.increment_call_count_fn = |_| true;
} }
} }