From: Mark Thom Date: Sat, 29 Feb 2020 06:42:40 +0000 (-0700) Subject: add s pointers for strings and partial strings, put_unsafe_value calls store earlier... X-Git-Tag: v0.8.119~66 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=2ebcd673c8f0a0a1a1f4c29ea01623644335f9f3;p=scryer-prolog.git add s pointers for strings and partial strings, put_unsafe_value calls store earlier to avoid unnecessary heap writes (#273) --- diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 143379e2..0cb9a42e 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -18,6 +18,7 @@ use std::cmp::Ordering; use std::io::{stdout, Write}; use std::mem; use std::ops::{Index, IndexMut}; +use std::rc::Rc; pub struct Ball { pub(super) boundary: usize, @@ -245,8 +246,33 @@ pub(super) enum MachineMode { Write, } +#[derive(Clone)] +pub(super) enum HeapPtr { + HeapCell(usize), + PStrLocation(usize, usize), + String(usize, Rc), +} + +impl HeapPtr { + #[inline] + pub(super) + fn as_addr(&self) -> Addr { + match self { + &HeapPtr::HeapCell(h) => Addr::HeapCell(h), + &HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n), + &HeapPtr::String(n, ref s) => Addr::Con(Constant::String(n, s.clone())), + } + } +} + +impl Default for HeapPtr { + fn default() -> Self { + HeapPtr::HeapCell(0) + } +} + pub struct MachineState { - pub(super) s: usize, + pub(super) s: HeapPtr, pub(super) p: CodePtr, pub(super) b: usize, pub(super) b0: usize, diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 6b8849a5..fb36d8cb 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -52,7 +52,7 @@ impl MachineState { pub(crate) fn new() -> Self { MachineState { - s: 0, + s: HeapPtr::default(), p: CodePtr::default(), b: 0, b0: 0, @@ -82,7 +82,7 @@ impl MachineState { pub(crate) fn with_small_heap() -> Self { MachineState { - s: 0, + s: HeapPtr::default(), p: CodePtr::default(), b: 0, b0: 0, @@ -645,6 +645,33 @@ impl MachineState { } } + fn increment_s_ptr(&mut self, rhs: usize) { + match &mut self.s { + HeapPtr::HeapCell(ref mut h) => { + *h += rhs; + } + HeapPtr::PStrLocation(h, n) => { + match &self.heap[*h] { + HeapCellValue::PartialString(ref pstr) => { + let s = pstr.block_as_str(); + + for c in s[*n ..].chars().take(rhs) { + *n += c.len_utf8(); + } + } + _ => { + unreachable!() + } + } + } + HeapPtr::String(ref mut n, ref s) => { + for c in s[*n ..].chars().take(rhs) { + *n += c.len_utf8(); + } + } + } + } + pub(super) fn unwind_trail(&mut self, a1: usize, a2: usize) { // the sequence is reversed to respect the chronology of trail @@ -1564,45 +1591,6 @@ impl MachineState { }; } - fn get_char_list(&mut self, offset: usize, s: Rc) - { - if let Some(c) = s[offset ..].chars().next() { - let h = self.heap.h(); - - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c)))); - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String( - offset + c.len_utf8(), - s, - )))); - - self.s = h; - self.mode = MachineMode::Read; - } - } - - fn get_partial_string_list(&mut self, pstr_h: usize, offset: usize) - { - let (c, pstr_tail) = - if let HeapCellValue::PartialString(ref pstr) = &self.heap[pstr_h] { - let s = pstr.block_as_str(); - - if let Some(c) = s[offset ..].chars().next() { - (c, Addr::PStrTail(pstr_h, offset + c.len_utf8())) - } else { - unreachable!() - } - } else { - unreachable!() - }; - - self.s = self.heap.h(); - - self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c)))); - self.heap.push(HeapCellValue::Addr(pstr_tail)); - - self.mode = MachineMode::Read; - } - pub(super) fn execute_fact_instr(&mut self, instr: &FactInstruction) { match instr { @@ -1618,14 +1606,16 @@ impl MachineState { match self.flags.double_quotes { DoubleQuotes::Chars | DoubleQuotes::Codes if s.len() > n => { - self.get_char_list(n, s) + self.s = HeapPtr::String(n, s); + self.mode = MachineMode::Read; } _ => { self.fail = true } }, Addr::PStrLocation(h, n) => { - self.get_partial_string_list(h, n) + self.s = HeapPtr::PStrLocation(h, n); + self.mode = MachineMode::Read; } addr @ Addr::AttrVar(_) | addr @ Addr::StackCell(..) @@ -1639,7 +1629,7 @@ impl MachineState { self.mode = MachineMode::Write; } Addr::Lis(a) => { - self.s = a; + self.s = HeapPtr::HeapCell(a); self.mode = MachineMode::Read; } _ => self.fail = true, @@ -1654,7 +1644,7 @@ impl MachineState { if let &HeapCellValue::NamedStr(narity, ref s, _) = result { if narity == arity && ct.name() == *s { - self.s = a + 1; + self.s = HeapPtr::HeapCell(a + 1); self.mode = MachineMode::Read; } else { self.fail = true; @@ -1685,7 +1675,7 @@ impl MachineState { &FactInstruction::UnifyConstant(ref c) => { match self.mode { MachineMode::Read => { - let addr = Addr::HeapCell(self.s); + let addr = self.s.as_addr(); self.write_constant_to_var(addr, c.clone()); } MachineMode::Write => { @@ -1693,11 +1683,11 @@ impl MachineState { } }; - self.s += 1; + self.increment_s_ptr(1); } &FactInstruction::UnifyVariable(reg) => { match self.mode { - MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s), + MachineMode::Read => self[reg] = self.s.as_addr(), MachineMode::Write => { let h = self.heap.h(); @@ -1706,15 +1696,13 @@ impl MachineState { } }; - self.s += 1; + self.increment_s_ptr(1); } &FactInstruction::UnifyLocalValue(reg) => { - let s = self.s; - match self.mode { MachineMode::Read => { let reg_addr = self[reg].clone(); - self.unify(reg_addr, Addr::HeapCell(s)); + self.unify(reg_addr, self.s.as_addr()); } MachineMode::Write => { let addr = self.deref(self[reg].clone()); @@ -1725,7 +1713,7 @@ impl MachineState { let val = self.heap[hc].clone(); self.heap.push(val); - self.s += 1; + self.increment_s_ptr(1); return; } @@ -1736,15 +1724,13 @@ impl MachineState { } }; - self.s += 1; + self.increment_s_ptr(1); } &FactInstruction::UnifyValue(reg) => { - let s = self.s; - match self.mode { MachineMode::Read => { let reg_addr = self[reg].clone(); - self.unify(reg_addr, Addr::HeapCell(s)); + self.unify(reg_addr, self.s.as_addr()); } MachineMode::Write => { let heap_val = self.store(self[reg].clone()); @@ -1752,11 +1738,11 @@ impl MachineState { } }; - self.s += 1; + self.increment_s_ptr(1); } &FactInstruction::UnifyVoid(n) => { match self.mode { - MachineMode::Read => self.s += n, + MachineMode::Read => self.increment_s_ptr(n), MachineMode::Write => { let h = self.heap.h(); @@ -1865,16 +1851,15 @@ impl MachineState { &QueryInstruction::PutStructure(ref ct, arity, reg) => { let h = self.heap.h(); - self.heap - .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); + self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec())); self[reg] = Addr::Str(h); } &QueryInstruction::PutUnsafeValue(n, arg) => { let e = self.e; - let addr = self.deref(Addr::StackCell(e, n)); + let addr = self.store(self.deref(Addr::StackCell(e, n))); if addr.is_protected(e) { - self.registers[arg] = self.store(addr); + self.registers[arg] = addr; } else { let h = self.heap.h(); @@ -3454,7 +3439,7 @@ impl MachineState { self.e = 0; self.b = 0; self.b0 = 0; - self.s = 0; + self.s = HeapPtr::default(); self.tr = 0; self.p = CodePtr::default(); self.cp = LocalCodePtr::default(); diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index accccbdc..5d20f00b 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -699,7 +699,7 @@ impl Machine { snapshot.e = self.machine_st.e; snapshot.b = self.machine_st.b; snapshot.b0 = self.machine_st.b0; - snapshot.s = self.machine_st.s; + snapshot.s = self.machine_st.s.clone(); snapshot.tr = self.machine_st.tr; snapshot.num_of_args = self.machine_st.num_of_args;