Skip to content

Commit 8db3009

Browse files
committed
ZJIT: Fix incorrect elision of call to BasicObject#!=
rb_obj_not_equal() uses rb_funcall(), so it's not `no_gc`, `leaf`, nor `elidable`.
1 parent cc8cfbc commit 8db3009

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

zjit/src/cruby_methods.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub fn init() -> Annotations {
221221
annotate!(rb_mKernel, "respond_to?", inline_kernel_respond_to_p);
222222
annotate!(rb_cBasicObject, "==", inline_basic_object_eq, types::BoolExact, no_gc, leaf, elidable);
223223
annotate!(rb_cBasicObject, "!", types::BoolExact, no_gc, leaf, elidable);
224-
annotate!(rb_cBasicObject, "!=", inline_basic_object_neq, types::BoolExact, no_gc, leaf, elidable);
224+
annotate!(rb_cBasicObject, "!=", inline_basic_object_neq, types::BoolExact);
225225
annotate!(rb_cBasicObject, "initialize", inline_basic_object_initialize);
226226
annotate!(rb_cInteger, "succ", inline_integer_succ);
227227
annotate!(rb_cInteger, "^", inline_integer_xor);

zjit/src/hir/opt_tests.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,52 @@ mod hir_opt_tests {
502502
");
503503
}
504504

505+
#[test]
506+
fn neq_with_side_effect_not_elided () {
507+
let result = eval("
508+
class CustomEq
509+
attr_reader :count
510+
511+
def ==(o)
512+
@count = @count.to_i + 1
513+
self.equal?(o)
514+
end
515+
end
516+
517+
def test(object)
518+
# intentionally unused, but also can't assign to underscore
519+
object != object
520+
nil
521+
end
522+
523+
custom = CustomEq.new
524+
test(custom)
525+
test(custom)
526+
527+
custom.count
528+
");
529+
assert_eq!(VALUE::fixnum_from_usize(2), result);
530+
assert_snapshot!(hir_string("test"), @r"
531+
fn test@<compiled>:13:
532+
bb0():
533+
EntryPoint interpreter
534+
v1:BasicObject = LoadSelf
535+
v2:BasicObject = GetLocal l0, SP@4
536+
Jump bb2(v1, v2)
537+
bb1(v5:BasicObject, v6:BasicObject):
538+
EntryPoint JIT(0)
539+
Jump bb2(v5, v6)
540+
bb2(v8:BasicObject, v9:BasicObject):
541+
PatchPoint MethodRedefined(CustomEq@0x1000, !=@0x1008, cme:0x1010)
542+
PatchPoint NoSingletonClass(CustomEq@0x1000)
543+
v28:HeapObject[class_exact:CustomEq] = GuardType v9, HeapObject[class_exact:CustomEq]
544+
v29:BoolExact = CCallWithFrame !=@0x1038, v28, v9
545+
v19:NilClass = Const Value(nil)
546+
CheckInterrupts
547+
Return v19
548+
");
549+
}
550+
505551
#[test]
506552
fn test_replace_guard_if_known_fixnum() {
507553
eval("

0 commit comments

Comments
 (0)