mirror of
https://github.com/ruby/ruby.git
synced 2026-08-03 13:08:59 +08:00
ZJIT: Add counters for throw and exception_handler (#17902)
This commit is contained in:
parent
2fd3c2edea
commit
61441f2d72
Notes:
git
2026-07-16 17:47:26 +00:00
Merged-By: k0kubun <takashikkbn@gmail.com>
@ -213,7 +213,7 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exc
|
||||
fn gen_iseq_entry_point(cb: &mut CodeBlock, iseq: IseqPtr, jit_exception: bool) -> Result<CodePtr, CompileError> {
|
||||
// We don't support exception handlers yet
|
||||
if jit_exception {
|
||||
return Err(CompileError::ExceptionHandler);
|
||||
return gen_exception_handler_counter(cb);
|
||||
}
|
||||
|
||||
let iseq_name = iseq_get_location(iseq, 0);
|
||||
@ -525,7 +525,6 @@ fn gen_function(cb: &mut CodeBlock, iseq: IseqPtr, version: IseqVersionRef, func
|
||||
debug!("ZJIT: gen_function: Failed to compile insn: {insn_id} {insn}. Generating side-exit.");
|
||||
gen_incr_counter(&mut asm, exit_counter_for_unhandled_hir_insn(&insn));
|
||||
let reason = match insn {
|
||||
Insn::Throw { .. } => SideExitReason::UnhandledHIRThrow,
|
||||
Insn::InvokeBuiltin { .. } => SideExitReason::UnhandledHIRInvokeBuiltin,
|
||||
_ => SideExitReason::UnhandledHIRUnknown(insn_id),
|
||||
};
|
||||
@ -784,7 +783,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
|
||||
&Insn::IsA { val, class } => gen_is_a(jit, asm, opnd!(val), opnd!(class)),
|
||||
&Insn::ArrayMax { ref elements, state } => gen_array_max(jit, asm, function, opnds!(elements), &function.frame_state(state)),
|
||||
&Insn::ArrayMin { ref elements, state } => gen_array_min(jit, asm, function, opnds!(elements), &function.frame_state(state)),
|
||||
&Insn::Throw { state, .. } => return Err(state),
|
||||
&Insn::Throw { state, .. } => no_output!(gen_throw(jit, asm, function, &function.frame_state(state))),
|
||||
&Insn::CondBranch { .. }
|
||||
| &Insn::Jump { .. } | Insn::Entries { .. } => unreachable!(),
|
||||
};
|
||||
@ -2582,6 +2581,12 @@ fn gen_return(asm: &mut Assembler, val: lir::Opnd) {
|
||||
asm.cret(C_RET_OPND);
|
||||
}
|
||||
|
||||
fn gen_throw(jit: &mut JITState, asm: &mut Assembler, function: &Function, state: &FrameState) {
|
||||
// TODO: Consider calling rb_vm_throw and propagating ec->tag->state to the interpreter.
|
||||
// Also consider making it a jump on method inlining.
|
||||
gen_side_exit(jit, asm, function, &SideExitReason::Throw, None, state);
|
||||
}
|
||||
|
||||
/// Compile Fixnum + Fixnum
|
||||
fn gen_fixnum_add(jit: &mut JITState, asm: &mut Assembler, function: &Function, left: lir::Opnd, right: lir::Opnd, state: &FrameState) -> lir::Opnd {
|
||||
// Add left + right and test for overflow
|
||||
@ -3971,6 +3976,19 @@ fn gen_compile_error_counter(cb: &mut CodeBlock, compile_error: &CompileError) -
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a JIT entry that just increments exit_exception_handler and exits
|
||||
fn gen_exception_handler_counter(cb: &mut CodeBlock) -> Result<CodePtr, CompileError> {
|
||||
let mut asm = Assembler::new();
|
||||
asm.new_block_without_id("exception_handler_counter");
|
||||
gen_incr_counter(&mut asm, Counter::exit_exception_handler);
|
||||
asm.cret(Qundef.into());
|
||||
|
||||
asm.compile(cb).map(|(code_ptr, gc_offsets)| {
|
||||
assert_eq!(0, gc_offsets.len());
|
||||
code_ptr
|
||||
})
|
||||
}
|
||||
|
||||
/// Given the number of spill slots needed for a function, return the number of bytes
|
||||
/// the function needs to allocate on the stack for the stack frame.
|
||||
fn aligned_stack_bytes(num_slots: usize) -> usize {
|
||||
|
||||
@ -553,6 +553,7 @@ pub enum SideExitReason {
|
||||
PatchPoint(Invariant),
|
||||
CalleeSideExit,
|
||||
Interrupt,
|
||||
Throw,
|
||||
BlockParamProxyNotIseqOrIfunc,
|
||||
BlockParamProxyNotNil,
|
||||
BlockParamProxyNotProc,
|
||||
|
||||
@ -185,6 +185,7 @@ make_counters! {
|
||||
exit {
|
||||
// exit_: Side exits reasons
|
||||
exit_compile_error,
|
||||
exit_exception_handler,
|
||||
exit_unhandled_newarray_send_min,
|
||||
exit_unhandled_newarray_send_hash,
|
||||
exit_unhandled_newarray_send_pack,
|
||||
@ -226,6 +227,7 @@ make_counters! {
|
||||
exit_patchpoint_root_box_only,
|
||||
exit_callee_side_exit,
|
||||
exit_interrupt,
|
||||
exit_throw,
|
||||
exit_stackoverflow,
|
||||
exit_block_param_proxy_not_iseq_or_ifunc,
|
||||
exit_block_param_proxy_not_nil,
|
||||
@ -349,7 +351,6 @@ make_counters! {
|
||||
compile_error_iseq_version_limit_reached,
|
||||
compile_error_iseq_stack_too_large,
|
||||
compile_error_native_stack_too_large,
|
||||
compile_error_exception_handler,
|
||||
compile_error_out_of_memory,
|
||||
compile_error_label_linking_failure,
|
||||
compile_error_jit_to_jit_optional,
|
||||
@ -369,9 +370,6 @@ make_counters! {
|
||||
compile_error_validation_misc_validation_error,
|
||||
|
||||
// unhandled_hir_insn_: Unhandled HIR instructions
|
||||
unhandled_hir_insn_array_max,
|
||||
unhandled_hir_insn_fixnum_div,
|
||||
unhandled_hir_insn_throw,
|
||||
unhandled_hir_insn_invokebuiltin,
|
||||
unhandled_hir_insn_unknown,
|
||||
|
||||
@ -523,7 +521,6 @@ pub enum CompileError {
|
||||
IseqVersionLimitReached,
|
||||
IseqStackTooLarge,
|
||||
NativeStackTooLarge,
|
||||
ExceptionHandler,
|
||||
OutOfMemory,
|
||||
ParseError(ParseError),
|
||||
/// When a ZJIT function is too large, the branches may have
|
||||
@ -542,7 +539,6 @@ pub fn exit_counter_for_compile_error(compile_error: &CompileError) -> Counter {
|
||||
IseqVersionLimitReached => compile_error_iseq_version_limit_reached,
|
||||
IseqStackTooLarge => compile_error_iseq_stack_too_large,
|
||||
NativeStackTooLarge => compile_error_native_stack_too_large,
|
||||
ExceptionHandler => compile_error_exception_handler,
|
||||
OutOfMemory => compile_error_out_of_memory,
|
||||
LabelLinkingFailure => compile_error_label_linking_failure,
|
||||
ParseError(parse_error) => match parse_error {
|
||||
@ -568,9 +564,6 @@ pub fn exit_counter_for_unhandled_hir_insn(insn: &crate::hir::Insn) -> Counter {
|
||||
use crate::hir::Insn::*;
|
||||
use crate::stats::Counter::*;
|
||||
match insn {
|
||||
ArrayMax { .. } => unhandled_hir_insn_array_max,
|
||||
FixnumDiv { .. } => unhandled_hir_insn_fixnum_div,
|
||||
Throw { .. } => unhandled_hir_insn_throw,
|
||||
InvokeBuiltin { .. } => unhandled_hir_insn_invokebuiltin,
|
||||
_ => unhandled_hir_insn_unknown,
|
||||
}
|
||||
@ -617,6 +610,7 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
|
||||
GuardSuperMethodEntry => exit_guard_super_method_entry,
|
||||
CalleeSideExit => exit_callee_side_exit,
|
||||
Interrupt => exit_interrupt,
|
||||
Throw => exit_throw,
|
||||
StackOverflow => exit_stackoverflow,
|
||||
BlockParamProxyNotIseqOrIfunc => exit_block_param_proxy_not_iseq_or_ifunc,
|
||||
BlockParamProxyNotNil => exit_block_param_proxy_not_nil,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user