@@ -7406,25 +7406,17 @@ mod hir_opt_tests {
74067406 bb3(v9:BasicObject, v10:BasicObject):
74077407 v15:CBool = HasType v10, ObjectSubclass[class_exact:C]
74087408 IfTrue v15, bb5(v9, v10, v10)
7409- v24:CBool = HasType v10, ObjectSubclass[class_exact:C]
7410- IfTrue v24, bb6(v9, v10, v10)
7411- v33:BasicObject = Send v10, :foo # SendFallbackReason: SendWithoutBlock: polymorphic fallback
7412- Jump bb4(v9, v10, v33)
7409+ v24:BasicObject = Send v10, :foo # SendFallbackReason: SendWithoutBlock: polymorphic fallback
7410+ Jump bb4(v9, v10, v24)
74137411 bb5(v16:BasicObject, v17:BasicObject, v18:BasicObject):
74147412 v20:ObjectSubclass[class_exact:C] = RefineType v18, ObjectSubclass[class_exact:C]
74157413 PatchPoint NoSingletonClass(C@0x1008)
74167414 PatchPoint MethodRedefined(C@0x1008, foo@0x1010, cme:0x1018)
7417- v46:BasicObject = GetIvar v20, :@foo
7418- Jump bb4(v16, v17, v46)
7419- bb6(v25:BasicObject, v26:BasicObject, v27:BasicObject):
7420- v29:ObjectSubclass[class_exact:C] = RefineType v27, ObjectSubclass[class_exact:C]
7421- PatchPoint NoSingletonClass(C@0x1008)
7422- PatchPoint MethodRedefined(C@0x1008, foo@0x1010, cme:0x1018)
7423- v49:BasicObject = GetIvar v29, :@foo
7424- Jump bb4(v25, v26, v49)
7425- bb4(v35:BasicObject, v36:BasicObject, v37:BasicObject):
7415+ v37:BasicObject = GetIvar v20, :@foo
7416+ Jump bb4(v16, v17, v37)
7417+ bb4(v26:BasicObject, v27:BasicObject, v28:BasicObject):
74267418 CheckInterrupts
7427- Return v37
7419+ Return v28
74287420 " ) ;
74297421 }
74307422
@@ -13834,6 +13826,210 @@ mod hir_opt_tests {
1383413826 " ) ;
1383513827 }
1383613828
13829+ #[ test]
13830+ fn specialize_polymorphic_send_fixnum_and_bignum ( ) {
13831+ // Fixnum and Bignum both have class Integer, but they should be
13832+ // treated as different types for polymorphic dispatch because
13833+ // Fixnum is an immediate and Bignum is a heap object.
13834+ set_call_threshold ( 4 ) ;
13835+ eval ( "
13836+ def test x
13837+ x.to_s
13838+ end
13839+
13840+ fixnum = 1
13841+ bignum = 10**100
13842+ test(fixnum)
13843+ test(bignum)
13844+ test(fixnum)
13845+ test(bignum)
13846+ " ) ;
13847+ assert_snapshot ! ( hir_string( "test" ) , @"
13848+ fn test@<compiled>:3:
13849+ bb1():
13850+ EntryPoint interpreter
13851+ v1:BasicObject = LoadSelf
13852+ v2:CPtr = LoadSP
13853+ v3:BasicObject = LoadField v2, :x@0x1000
13854+ Jump bb3(v1, v3)
13855+ bb2():
13856+ EntryPoint JIT(0)
13857+ v6:BasicObject = LoadArg :self@0
13858+ v7:BasicObject = LoadArg :x@1
13859+ Jump bb3(v6, v7)
13860+ bb3(v9:BasicObject, v10:BasicObject):
13861+ v15:CBool = HasType v10, Fixnum
13862+ IfTrue v15, bb5(v9, v10, v10)
13863+ v24:CBool = HasType v10, Bignum
13864+ IfTrue v24, bb6(v9, v10, v10)
13865+ v33:BasicObject = Send v10, :to_s # SendFallbackReason: SendWithoutBlock: polymorphic fallback
13866+ Jump bb4(v9, v10, v33)
13867+ bb5(v16:BasicObject, v17:BasicObject, v18:BasicObject):
13868+ v20:Fixnum = RefineType v18, Fixnum
13869+ PatchPoint MethodRedefined(Integer@0x1008, to_s@0x1010, cme:0x1018)
13870+ v46:StringExact = CCallVariadic v20, :Integer#to_s@0x1040
13871+ Jump bb4(v16, v17, v46)
13872+ bb6(v25:BasicObject, v26:BasicObject, v27:BasicObject):
13873+ v29:Bignum = RefineType v27, Bignum
13874+ PatchPoint MethodRedefined(Integer@0x1008, to_s@0x1010, cme:0x1018)
13875+ v49:StringExact = CCallVariadic v29, :Integer#to_s@0x1040
13876+ Jump bb4(v25, v26, v49)
13877+ bb4(v35:BasicObject, v36:BasicObject, v37:BasicObject):
13878+ CheckInterrupts
13879+ Return v37
13880+ " ) ;
13881+ }
13882+
13883+ #[ test]
13884+ fn specialize_polymorphic_send_flonum_and_heap_float ( ) {
13885+ set_call_threshold ( 4 ) ;
13886+ eval ( "
13887+ def test x
13888+ x.to_s
13889+ end
13890+
13891+ flonum = 1.5
13892+ heap_float = 1.7976931348623157e+308
13893+ test(flonum)
13894+ test(heap_float)
13895+ test(flonum)
13896+ test(heap_float)
13897+ " ) ;
13898+ assert_snapshot ! ( hir_string( "test" ) , @"
13899+ fn test@<compiled>:3:
13900+ bb1():
13901+ EntryPoint interpreter
13902+ v1:BasicObject = LoadSelf
13903+ v2:CPtr = LoadSP
13904+ v3:BasicObject = LoadField v2, :x@0x1000
13905+ Jump bb3(v1, v3)
13906+ bb2():
13907+ EntryPoint JIT(0)
13908+ v6:BasicObject = LoadArg :self@0
13909+ v7:BasicObject = LoadArg :x@1
13910+ Jump bb3(v6, v7)
13911+ bb3(v9:BasicObject, v10:BasicObject):
13912+ v15:CBool = HasType v10, Flonum
13913+ IfTrue v15, bb5(v9, v10, v10)
13914+ v24:CBool = HasType v10, HeapFloat
13915+ IfTrue v24, bb6(v9, v10, v10)
13916+ v33:BasicObject = Send v10, :to_s # SendFallbackReason: SendWithoutBlock: polymorphic fallback
13917+ Jump bb4(v9, v10, v33)
13918+ bb5(v16:BasicObject, v17:BasicObject, v18:BasicObject):
13919+ v20:Flonum = RefineType v18, Flonum
13920+ PatchPoint MethodRedefined(Float@0x1008, to_s@0x1010, cme:0x1018)
13921+ v46:BasicObject = CCallWithFrame v20, :Float#to_s@0x1040
13922+ Jump bb4(v16, v17, v46)
13923+ bb6(v25:BasicObject, v26:BasicObject, v27:BasicObject):
13924+ v29:HeapFloat = RefineType v27, HeapFloat
13925+ PatchPoint MethodRedefined(Float@0x1008, to_s@0x1010, cme:0x1018)
13926+ v49:BasicObject = CCallWithFrame v29, :Float#to_s@0x1040
13927+ Jump bb4(v25, v26, v49)
13928+ bb4(v35:BasicObject, v36:BasicObject, v37:BasicObject):
13929+ CheckInterrupts
13930+ Return v37
13931+ " ) ;
13932+ }
13933+
13934+ #[ test]
13935+ fn specialize_polymorphic_send_static_and_dynamic_symbol ( ) {
13936+ set_call_threshold ( 4 ) ;
13937+ eval ( "
13938+ def test x
13939+ x.to_s
13940+ end
13941+
13942+ static_sym = :foo
13943+ dynamic_sym = (\" zjit_dynamic_\" + Object.new.object_id.to_s).to_sym
13944+ test static_sym
13945+ test dynamic_sym
13946+ test static_sym
13947+ test dynamic_sym
13948+ " ) ;
13949+ assert_snapshot ! ( hir_string( "test" ) , @"
13950+ fn test@<compiled>:3:
13951+ bb1():
13952+ EntryPoint interpreter
13953+ v1:BasicObject = LoadSelf
13954+ v2:CPtr = LoadSP
13955+ v3:BasicObject = LoadField v2, :x@0x1000
13956+ Jump bb3(v1, v3)
13957+ bb2():
13958+ EntryPoint JIT(0)
13959+ v6:BasicObject = LoadArg :self@0
13960+ v7:BasicObject = LoadArg :x@1
13961+ Jump bb3(v6, v7)
13962+ bb3(v9:BasicObject, v10:BasicObject):
13963+ v15:CBool = HasType v10, StaticSymbol
13964+ IfTrue v15, bb5(v9, v10, v10)
13965+ v24:CBool = HasType v10, DynamicSymbol
13966+ IfTrue v24, bb6(v9, v10, v10)
13967+ v33:BasicObject = Send v10, :to_s # SendFallbackReason: SendWithoutBlock: polymorphic fallback
13968+ Jump bb4(v9, v10, v33)
13969+ bb5(v16:BasicObject, v17:BasicObject, v18:BasicObject):
13970+ v20:StaticSymbol = RefineType v18, StaticSymbol
13971+ PatchPoint MethodRedefined(Symbol@0x1008, to_s@0x1010, cme:0x1018)
13972+ v48:StringExact = InvokeBuiltin leaf <inline_expr>, v20
13973+ Jump bb4(v16, v17, v48)
13974+ bb6(v25:BasicObject, v26:BasicObject, v27:BasicObject):
13975+ v29:DynamicSymbol = RefineType v27, DynamicSymbol
13976+ PatchPoint MethodRedefined(Symbol@0x1008, to_s@0x1010, cme:0x1018)
13977+ v49:StringExact = InvokeBuiltin leaf <inline_expr>, v29
13978+ Jump bb4(v25, v26, v49)
13979+ bb4(v35:BasicObject, v36:BasicObject, v37:BasicObject):
13980+ CheckInterrupts
13981+ Return v37
13982+ " ) ;
13983+ }
13984+
13985+ #[ test]
13986+ fn specialize_polymorphic_send_iseq_duplicate_class_profiles ( ) {
13987+ set_call_threshold ( 4 ) ;
13988+ eval ( "
13989+ class C
13990+ def foo = 3
13991+ end
13992+
13993+ O1 = C.new
13994+ O1.instance_variable_set(:@foo, 1)
13995+ O2 = C.new
13996+ O2.instance_variable_set(:@bar, 2)
13997+
13998+ def test o
13999+ o.foo
14000+ end
14001+
14002+ test O1; test O2; test O1; test O2
14003+ " ) ;
14004+ assert_snapshot ! ( hir_string( "test" ) , @"
14005+ fn test@<compiled>:12:
14006+ bb1():
14007+ EntryPoint interpreter
14008+ v1:BasicObject = LoadSelf
14009+ v2:CPtr = LoadSP
14010+ v3:BasicObject = LoadField v2, :o@0x1000
14011+ Jump bb3(v1, v3)
14012+ bb2():
14013+ EntryPoint JIT(0)
14014+ v6:BasicObject = LoadArg :self@0
14015+ v7:BasicObject = LoadArg :o@1
14016+ Jump bb3(v6, v7)
14017+ bb3(v9:BasicObject, v10:BasicObject):
14018+ v15:CBool = HasType v10, ObjectSubclass[class_exact:C]
14019+ IfTrue v15, bb5(v9, v10, v10)
14020+ v24:BasicObject = Send v10, :foo # SendFallbackReason: SendWithoutBlock: polymorphic fallback
14021+ Jump bb4(v9, v10, v24)
14022+ bb5(v16:BasicObject, v17:BasicObject, v18:BasicObject):
14023+ PatchPoint NoSingletonClass(C@0x1008)
14024+ PatchPoint MethodRedefined(C@0x1008, foo@0x1010, cme:0x1018)
14025+ v38:Fixnum[3] = Const Value(3)
14026+ Jump bb4(v16, v17, v38)
14027+ bb4(v26:BasicObject, v27:BasicObject, v28:BasicObject):
14028+ CheckInterrupts
14029+ Return v28
14030+ " ) ;
14031+ }
14032+
1383714033 #[ test]
1383814034 fn upgrade_self_type_to_heap_after_setivar ( ) {
1383914035 eval ( "
0 commit comments