From bcd9c87d15c34e93e5c6dfa5dcc82fde2d10ddb5 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Thu, 21 Aug 2025 16:49:34 -0400 Subject: 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. --- zjit/src/hir.rs | 17 ++++++++++++----- 1 file 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 { 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 { 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 { 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 { 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 { } 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 { } 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 } -- cgit v1.2.3