Skip to content

Commit

Permalink
scan registers of instructions leading to verify_attributes interrupt…
Browse files Browse the repository at this point in the history
… to find the number of registers to save (mthom#2307)
  • Loading branch information
mthom committed Jan 26, 2024
1 parent 6111f72 commit 6fe8f64
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 12 deletions.
35 changes: 31 additions & 4 deletions build/instructions_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@ enum InstructionTemplate {
#[strum_discriminants(strum(props(Arity = "0", Name = "install_verify_attr")))]
InstallVerifyAttr,
// call verify_attrs.
#[strum_discriminants(strum(props(Arity = "0", Name = "verify_attr_interrupt")))]
VerifyAttrInterrupt,
#[strum_discriminants(strum(props(Arity = "1", Name = "verify_attr_interrupt")))]
VerifyAttrInterrupt(usize),
// procedures
CallClause(ClauseType, usize, usize, bool, bool), // ClauseType,
// arity,
Expand Down Expand Up @@ -1153,6 +1153,33 @@ fn generate_instruction_preface() -> TokenStream {
pub type CodeDeque = VecDeque<Instruction>;

impl Instruction {
#[inline]
pub fn registers(&self) -> Vec<RegType> {
match self {
&Instruction::GetConstant(_, _, r) => vec![r],
&Instruction::GetList(_, r) => vec![r],
&Instruction::GetPartialString(_, _, r, _) => vec![r],
&Instruction::GetStructure(_, _, _, r) => vec![r],
&Instruction::GetVariable(r, t) => vec![r, temp_v!(t)],
&Instruction::GetValue(r, t) => vec![r, temp_v!(t)],
&Instruction::UnifyLocalValue(r) => vec![r],
&Instruction::UnifyVariable(r) => vec![r],
&Instruction::PutConstant(_, _, r) => vec![r],
&Instruction::PutList(_, r) => vec![r],
&Instruction::PutPartialString(_, _, r, _) => vec![r],
&Instruction::PutStructure(_, _, r) => vec![r],
&Instruction::PutValue(r, t) => vec![r, temp_v!(t)],
&Instruction::PutVariable(r, t) => vec![r, temp_v!(t)],
&Instruction::SetLocalValue(r) => vec![r],
&Instruction::SetVariable(r) => vec![r],
&Instruction::SetValue(r) => vec![r],
&Instruction::GetLevel(r) => vec![r],
&Instruction::GetPrevLevel(r) => vec![r],
&Instruction::GetCutPoint(r) => vec![r],
_ => vec![],
}
}

#[inline]
pub fn to_indexing_line_mut(&mut self) -> Option<&mut Vec<IndexingLine>> {
match self {
Expand Down Expand Up @@ -1243,8 +1270,8 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::InstallVerifyAttr => {
functor!(atom!("install_verify_attr"))
}
&Instruction::VerifyAttrInterrupt => {
functor!(atom!("verify_attr_interrupt"))
&Instruction::VerifyAttrInterrupt(arity) => {
functor!(atom!("verify_attr_interrupt"), [fixnum(arity)])
}
&Instruction::DynamicElse(birth, death, next_or_fail) => {
match (death, next_or_fail) {
Expand Down
19 changes: 14 additions & 5 deletions src/machine/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,20 +557,29 @@ impl Machine {
}

let mut p = self.machine_st.p;
let mut arity = 0;

while self.code[p].is_head_instr() {
for r in self.code[p].registers() {
if let RegType::Temp(t) = r {
arity = std::cmp::max(arity, t);
}
}

p += 1;
}

let instr =
std::mem::replace(&mut self.code[p], Instruction::VerifyAttrInterrupt);
let instr = std::mem::replace(
&mut self.code[p],
Instruction::VerifyAttrInterrupt(arity),
);

self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
self.machine_st.attr_var_init.cp = p;
}
&Instruction::VerifyAttrInterrupt => {
let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
let arity = std::cmp::max(arity, self.machine_st.num_of_args);
&Instruction::VerifyAttrInterrupt(arity) => {
// let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
// let arity = std::cmp::max(arity, self.machine_st.num_of_args);
self.run_verify_attr_interrupt(arity);
}
&Instruction::Add(ref a1, ref a2, t) => {
Expand Down
2 changes: 1 addition & 1 deletion src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ impl Machine {
self.code.extend(vec![
Instruction::BreakFromDispatchLoop,
Instruction::InstallVerifyAttr,
Instruction::VerifyAttrInterrupt,
Instruction::VerifyAttrInterrupt(0),
Instruction::BreakFromDispatchLoop, // the location of LIB_QUERY_SUCCESS
Instruction::ExecuteTermGreaterThan,
Instruction::ExecuteTermLessThan,
Expand Down
4 changes: 2 additions & 2 deletions src/machine/system_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5739,11 +5739,11 @@ impl Machine {
#[inline(always)]
pub(super) fn restore_instr_at_verify_attr_interrupt(&mut self) {
match &self.code[VERIFY_ATTR_INTERRUPT_LOC] {
&Instruction::VerifyAttrInterrupt => {}
&Instruction::VerifyAttrInterrupt(_) => {}
_ => {
let instr = mem::replace(
&mut self.code[VERIFY_ATTR_INTERRUPT_LOC],
Instruction::VerifyAttrInterrupt,
Instruction::VerifyAttrInterrupt(0),
);

self.code[self.machine_st.attr_var_init.cp] = instr;
Expand Down

0 comments on commit 6fe8f64

Please sign in to comment.