Skip to content

Commit 2a4f47b

Browse files
committed
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
1 parent f5acefc commit 2a4f47b

4 files changed

Lines changed: 36 additions & 13 deletions

File tree

insns.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ opt_nil_p
996996
(CALL_DATA cd)
997997
(VALUE recv)
998998
(VALUE val)
999+
// attr bool zjit_profile = true;
9991000
{
10001001
val = vm_opt_nil_p(GET_ISEQ(), cd, recv);
10011002

zjit/src/cruby_bindings.inc.rs

Lines changed: 13 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

zjit/src/hir.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ impl Function {
15471547
} else {
15481548
let iseq_insn_idx = fun.frame_state(state).insn_idx;
15491549
let Some(recv_type) = fun.profiled_type_of_at(self_val, iseq_insn_idx) else { return Err(()) };
1550-
let Some(recv_class) = recv_type.exact_ruby_class() else { return Err(()) };
1550+
let Some(recv_class) = recv_type.runtime_exact_ruby_class() else { return Err(()) };
15511551
(recv_class, Some(recv_type.unspecialized()))
15521552
};
15531553

@@ -6641,4 +6641,24 @@ mod opt_tests {
66416641
Return v5
66426642
"#]]);
66436643
}
6644+
6645+
#[test]
6646+
fn test_guard_nil_for_nil_opt() {
6647+
eval("
6648+
def test(val)
6649+
val.nil?
6650+
end
6651+
6652+
test(nil)
6653+
test(nil)
6654+
");
6655+
assert_optimized_method_hir("test", expect![[r#"
6656+
fn test:
6657+
bb0(v0:BasicObject, v1:BasicObject):
6658+
PatchPoint MethodRedefined(NilClass@0x1000, nil?@0x1008)
6659+
v7:NilClassExact = GuardType v1, NilClassExact
6660+
v8:TrueClassExact = CCall nil?@0x1010, v7
6661+
Return v8
6662+
"#]]);
6663+
}
66446664
}

zjit/src/profile.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub extern "C" fn rb_zjit_profile_insn(opcode: ruby_vminsn_type, ec: EcPtr) {
5151
/// Profile a YARV instruction
5252
fn profile_insn(profiler: &mut Profiler, opcode: ruby_vminsn_type) {
5353
match opcode {
54+
YARVINSN_opt_nil_p => profile_operands(profiler, 1),
5455
YARVINSN_opt_plus => profile_operands(profiler, 2),
5556
YARVINSN_opt_minus => profile_operands(profiler, 2),
5657
YARVINSN_opt_mult => profile_operands(profiler, 2),

0 commit comments

Comments
 (0)