summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <ruby@bernsteinbear.com>2025-08-21 16:49:34 -0400
committerMax Bernstein <tekknolagi@gmail.com>2025-08-22 10:34:11 -0700
commitbcd9c87d15c34e93e5c6dfa5dcc82fde2d10ddb5 (patch)
tree4f5f25f81582eb4a2dcc8dc24867cb5bce54bfc4
parentd690e8327644102386deeaeee8eb4818c24fd38b (diff)
ZJIT: Eagerly place CheckInterrupts
Ideally we would do this lazily post optimization, but this is easier for now: we already have the requisite Snapshots available.
-rw-r--r--zjit/src/hir.rs17
1 files changed, 12 insertions, 5 deletions
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index 358ecc58a9..f68d85a42d 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -3038,10 +3038,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
state.stack_push(fun.push_insn(block, Insn::GetConstantPath { ic, state: snapshot }));
}
YARVINSN_branchunless => {
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
let offset = get_arg(pc, 0).as_i64();
let val = state.stack_pop()?;
let test_id = fun.push_insn(block, Insn::Test { val });
- // TODO(max): Check interrupts
let target_idx = insn_idx_at_offset(insn_idx, offset);
let target = insn_idx_to_block[&target_idx];
let _branch_id = fun.push_insn(block, Insn::IfFalse {
@@ -3051,10 +3052,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
queue.push_back((state.clone(), target, target_idx));
}
YARVINSN_branchif => {
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
let offset = get_arg(pc, 0).as_i64();
let val = state.stack_pop()?;
let test_id = fun.push_insn(block, Insn::Test { val });
- // TODO(max): Check interrupts
let target_idx = insn_idx_at_offset(insn_idx, offset);
let target = insn_idx_to_block[&target_idx];
let _branch_id = fun.push_insn(block, Insn::IfTrue {
@@ -3064,10 +3066,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
queue.push_back((state.clone(), target, target_idx));
}
YARVINSN_branchnil => {
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
let offset = get_arg(pc, 0).as_i64();
let val = state.stack_pop()?;
let test_id = fun.push_insn(block, Insn::IsNil { val });
- // TODO(max): Check interrupts
let target_idx = insn_idx_at_offset(insn_idx, offset);
let target = insn_idx_to_block[&target_idx];
let _branch_id = fun.push_insn(block, Insn::IfTrue {
@@ -3077,8 +3080,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
queue.push_back((state.clone(), target, target_idx));
}
YARVINSN_opt_new => {
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
let offset = get_arg(pc, 1).as_i64();
- // TODO(max): Check interrupts
let target_idx = insn_idx_at_offset(insn_idx, offset);
let target = insn_idx_to_block[&target_idx];
// Skip the fast-path and go straight to the fallback code. We will let the
@@ -3089,7 +3093,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
}
YARVINSN_jump => {
let offset = get_arg(pc, 0).as_i64();
- // TODO(max): Check interrupts
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
let target_idx = insn_idx_at_offset(insn_idx, offset);
let target = insn_idx_to_block[&target_idx];
let _branch_id = fun.push_insn(block, Insn::Jump(
@@ -3238,6 +3243,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
}
YARVINSN_leave => {
+ let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
+ fun.push_insn(block, Insn::CheckInterrupts { state: exit_id });
fun.push_insn(block, Insn::Return { val: state.stack_pop()? });
break; // Don't enqueue the next block as a successor
}