mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
ZJIT: Profile nil? calls
This allows ZJIT to profile `nil?` calls and create type guards for its receiver. - Add `zjit_profile` to `opt_nil_p` insn - Start profiling `opt_nil_p` calls - Use `runtime_exact_ruby_class` instead of `exact_ruby_class` to determine the profiled receiver class
This commit is contained in:
parent
b16047088a
commit
79915e6f78
@ -996,6 +996,7 @@ opt_nil_p
|
||||
(CALL_DATA cd)
|
||||
(VALUE recv)
|
||||
(VALUE val)
|
||||
// attr bool zjit_profile = true;
|
||||
{
|
||||
val = vm_opt_nil_p(GET_ISEQ(), cd, recv);
|
||||
|
||||
|
||||
25
zjit/src/cruby_bindings.inc.rs
generated
25
zjit/src/cruby_bindings.inc.rs
generated
@ -683,18 +683,19 @@ pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 219;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 220;
|
||||
pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 221;
|
||||
pub const YARVINSN_zjit_opt_send_without_block: ruby_vminsn_type = 222;
|
||||
pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 223;
|
||||
pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 224;
|
||||
pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 225;
|
||||
pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 226;
|
||||
pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 227;
|
||||
pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 228;
|
||||
pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 229;
|
||||
pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 230;
|
||||
pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 231;
|
||||
pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 232;
|
||||
pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 233;
|
||||
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 234;
|
||||
pub const YARVINSN_zjit_opt_nil_p: ruby_vminsn_type = 223;
|
||||
pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 224;
|
||||
pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 225;
|
||||
pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 226;
|
||||
pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 227;
|
||||
pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 228;
|
||||
pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 229;
|
||||
pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 230;
|
||||
pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 231;
|
||||
pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 232;
|
||||
pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 233;
|
||||
pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 234;
|
||||
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 235;
|
||||
pub type ruby_vminsn_type = u32;
|
||||
pub type rb_iseq_callback = ::std::option::Option<
|
||||
unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),
|
||||
|
||||
@ -1547,7 +1547,7 @@ impl Function {
|
||||
} else {
|
||||
let iseq_insn_idx = fun.frame_state(state).insn_idx;
|
||||
let Some(recv_type) = fun.profiled_type_of_at(self_val, iseq_insn_idx) else { return Err(()) };
|
||||
let Some(recv_class) = recv_type.exact_ruby_class() else { return Err(()) };
|
||||
let Some(recv_class) = recv_type.runtime_exact_ruby_class() else { return Err(()) };
|
||||
(recv_class, Some(recv_type.unspecialized()))
|
||||
};
|
||||
|
||||
@ -6659,4 +6659,21 @@ mod opt_tests {
|
||||
Return v5
|
||||
"#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_guard_nil_for_nil_opt() {
|
||||
eval("
|
||||
def test(val) = val.nil?
|
||||
|
||||
test(nil)
|
||||
");
|
||||
assert_optimized_method_hir("test", expect![[r#"
|
||||
fn test:
|
||||
bb0(v0:BasicObject, v1:BasicObject):
|
||||
PatchPoint MethodRedefined(NilClass@0x1000, nil?@0x1008)
|
||||
v7:NilClassExact = GuardType v1, NilClassExact
|
||||
v8:TrueClassExact = CCall nil?@0x1010, v7
|
||||
Return v8
|
||||
"#]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ pub extern "C" fn rb_zjit_profile_insn(opcode: ruby_vminsn_type, ec: EcPtr) {
|
||||
/// Profile a YARV instruction
|
||||
fn profile_insn(profiler: &mut Profiler, opcode: ruby_vminsn_type) {
|
||||
match opcode {
|
||||
YARVINSN_opt_nil_p => profile_operands(profiler, 1),
|
||||
YARVINSN_opt_plus => profile_operands(profiler, 2),
|
||||
YARVINSN_opt_minus => profile_operands(profiler, 2),
|
||||
YARVINSN_opt_mult => profile_operands(profiler, 2),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user