Skip to content

Commit 0594646

Browse files
authored
ZJIT: Don't push frame for Hash#size (ruby#14871)
`Hash#size` was not in "Top-20 not annotated C methods" on lobsters so our before / after benchmarks are not very helpful for this change. <details> <summary>Before</summary> <br> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (60.9% of total 10,963,289): Kernel#is_a?: 1,047,725 ( 9.6%) String#<<: 861,497 ( 7.9%) Hash#[]=: 740,725 ( 6.8%) Regexp#match?: 398,297 ( 3.6%) String#empty?: 354,809 ( 3.2%) Hash#key?: 349,173 ( 3.2%) String#start_with?: 337,387 ( 3.1%) Kernel#respond_to?: 321,134 ( 2.9%) TrueClass#===: 239,657 ( 2.2%) ObjectSpace::WeakKeyMap#[]: 238,988 ( 2.2%) FalseClass#===: 234,777 ( 2.1%) Array#include?: 213,229 ( 1.9%) Kernel#block_given?: 181,801 ( 1.7%) Kernel#dup: 179,349 ( 1.6%) Kernel#kind_of?: 174,710 ( 1.6%) BasicObject#!=: 174,448 ( 1.6%) String.new: 167,716 ( 1.5%) Hash#fetch: 160,704 ( 1.5%) String#==: 158,858 ( 1.4%) Process.clock_gettime: 145,002 ( 1.3%) Top-20 not annotated C methods (61.8% of total 11,128,431): Kernel#is_a?: 1,226,218 (11.0%) String#<<: 861,497 ( 7.7%) Hash#[]=: 740,904 ( 6.7%) Regexp#match?: 398,297 ( 3.6%) String#empty?: 362,047 ( 3.3%) Hash#key?: 349,173 ( 3.1%) String#start_with?: 337,387 ( 3.0%) Kernel#respond_to?: 321,134 ( 2.9%) TrueClass#===: 239,657 ( 2.2%) ObjectSpace::WeakKeyMap#[]: 238,988 ( 2.1%) FalseClass#===: 234,777 ( 2.1%) Array#include?: 213,229 ( 1.9%) Kernel#block_given?: 191,670 ( 1.7%) Kernel#dup: 179,356 ( 1.6%) Kernel#kind_of?: 174,745 ( 1.6%) BasicObject#!=: 174,632 ( 1.6%) String.new: 167,716 ( 1.5%) String#==: 164,789 ( 1.5%) Hash#fetch: 160,704 ( 1.4%) Process.clock_gettime: 145,002 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 62,854): cfunc: 47,647 (75.8%) iseq: 15,207 (24.2%) Top-6 not optimized method types for send_without_block (100.0% of total 4,497,956): iseq: 2,236,049 (49.7%) bmethod: 993,299 (22.1%) optimized: 949,781 (21.1%) alias: 313,166 ( 7.0%) null: 5,106 ( 0.1%) cfunc: 555 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,255,830): invokesuper: 2,371,027 (55.7%) invokeblock: 811,314 (19.1%) sendforward: 506,486 (11.9%) opt_eq: 415,294 ( 9.8%) opt_plus: 77,090 ( 1.8%) opt_minus: 36,228 ( 0.9%) opt_send_without_block: 20,297 ( 0.5%) opt_neq: 7,248 ( 0.2%) opt_mult: 6,754 ( 0.2%) opt_or: 3,617 ( 0.1%) opt_lt: 348 ( 0.0%) opt_ge: 91 ( 0.0%) opt_gt: 36 ( 0.0%) Top-9 send fallback reasons (100.0% of total 24,945,472): send_without_block_polymorphic: 9,308,731 (37.3%) send_no_profiles: 5,907,934 (23.7%) send_without_block_not_optimized_method_type: 4,497,956 (18.0%) not_optimized_instruction: 4,255,830 (17.1%) send_without_block_no_profiles: 887,000 ( 3.6%) send_not_optimized_method_type: 62,854 ( 0.3%) send_without_block_cfunc_array_variadic: 15,138 ( 0.1%) obj_to_string_not_string: 9,767 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 707,558): expandarray: 347,142 (49.1%) checkkeyword: 190,708 (27.0%) getclassvariable: 59,296 ( 8.4%) getblockparam: 49,122 ( 6.9%) invokesuperforward: 48,163 ( 6.8%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 840 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 3,649,990): register_spill_on_alloc: 3,428,507 (93.9%) register_spill_on_ccall: 221,483 ( 6.1%) Top-17 side exit reasons (100.0% of total 10,833,336): compile_error: 3,649,990 (33.7%) guard_type_failure: 2,681,177 (24.7%) guard_shape_failure: 1,897,864 (17.5%) unhandled_yarv_insn: 707,558 ( 6.5%) block_param_proxy_not_iseq_or_ifunc: 536,761 ( 5.0%) unhandled_kwarg: 456,394 ( 4.2%) unknown_newarray_send: 314,671 ( 2.9%) patchpoint_stable_constant_names: 229,825 ( 2.1%) unhandled_splat: 129,577 ( 1.2%) patchpoint_no_singleton_class: 108,465 ( 1.0%) unhandled_hir_insn: 76,401 ( 0.7%) patchpoint_method_redefined: 20,493 ( 0.2%) block_param_proxy_modified: 20,204 ( 0.2%) patchpoint_no_ep_escape: 3,765 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 13 ( 0.0%) send_count: 67,968,616 dynamic_send_count: 24,945,472 (36.7%) optimized_send_count: 43,023,144 (63.3%) iseq_optimized_send_count: 18,621,234 (27.4%) inline_cfunc_optimized_send_count: 13,438,621 (19.8%) non_variadic_cfunc_optimized_send_count: 8,333,523 (12.3%) variadic_cfunc_optimized_send_count: 2,629,766 ( 3.9%) dynamic_getivar_count: 7,351,238 dynamic_setivar_count: 7,267,701 compiled_iseq_count: 4,772 failed_iseq_count: 465 compile_time: 7,006ms profile_time: 52ms gc_time: 46ms invalidation_time: 123ms vm_write_pc_count: 63,668,147 vm_write_sp_count: 62,343,075 vm_write_locals_count: 62,343,075 vm_write_stack_count: 62,343,075 vm_write_to_parent_iseq_local_count: 292,130 vm_read_from_parent_iseq_local_count: 6,623,223 code_region_bytes: 22,724,608 side_exit_count: 10,833,336 total_insn_count: 519,162,657 vm_insn_count: 164,942,584 zjit_insn_count: 354,220,073 ratio_in_zjit: 68.2% ``` </details> <details> <summary>After</summary> <br> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (61.1% of total 10,915,774): Kernel#is_a?: 1,027,957 ( 9.4%) String#<<: 851,954 ( 7.8%) Hash#[]=: 740,863 ( 6.8%) Regexp#match?: 398,265 ( 3.6%) String#empty?: 353,775 ( 3.2%) Hash#key?: 349,161 ( 3.2%) String#start_with?: 337,386 ( 3.1%) Kernel#respond_to?: 316,003 ( 2.9%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.2%) TrueClass#===: 235,771 ( 2.2%) FalseClass#===: 231,144 ( 2.1%) Array#include?: 211,340 ( 1.9%) Hash#fetch: 204,703 ( 1.9%) Kernel#block_given?: 181,791 ( 1.7%) Kernel#dup: 179,337 ( 1.6%) BasicObject#!=: 174,430 ( 1.6%) String.new: 166,696 ( 1.5%) Kernel#kind_of?: 165,600 ( 1.5%) String#==: 154,751 ( 1.4%) Process.clock_gettime: 144,992 ( 1.3%) Top-20 not annotated C methods (62.0% of total 11,078,184): Kernel#is_a?: 1,209,975 (10.9%) String#<<: 851,954 ( 7.7%) Hash#[]=: 741,042 ( 6.7%) Regexp#match?: 398,265 ( 3.6%) String#empty?: 361,013 ( 3.3%) Hash#key?: 349,161 ( 3.2%) String#start_with?: 337,386 ( 3.0%) Kernel#respond_to?: 316,003 ( 2.9%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.2%) TrueClass#===: 235,771 ( 2.1%) FalseClass#===: 231,144 ( 2.1%) Array#include?: 211,340 ( 1.9%) Hash#fetch: 204,703 ( 1.8%) Kernel#block_given?: 191,660 ( 1.7%) Kernel#dup: 179,344 ( 1.6%) BasicObject#!=: 174,614 ( 1.6%) String.new: 166,696 ( 1.5%) Kernel#kind_of?: 165,634 ( 1.5%) String#==: 160,682 ( 1.5%) Process.clock_gettime: 144,992 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 71,084): cfunc: 47,638 (67.0%) iseq: 23,446 (33.0%) Top-6 not optimized method types for send_without_block (100.0% of total 4,469,252): iseq: 2,217,500 (49.6%) bmethod: 985,636 (22.1%) optimized: 949,705 (21.2%) alias: 310,751 ( 7.0%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,264,988): invokesuper: 2,346,307 (55.0%) invokeblock: 809,211 (19.0%) sendforward: 505,452 (11.9%) opt_eq: 454,244 (10.7%) opt_plus: 74,059 ( 1.7%) opt_minus: 36,228 ( 0.8%) opt_send_without_block: 21,396 ( 0.5%) opt_neq: 7,247 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,617 ( 0.1%) opt_lt: 348 ( 0.0%) opt_ge: 91 ( 0.0%) opt_gt: 36 ( 0.0%) Top-9 send fallback reasons (100.0% of total 25,044,791): send_without_block_polymorphic: 9,439,021 (37.7%) send_no_profiles: 5,892,924 (23.5%) send_without_block_not_optimized_method_type: 4,469,252 (17.8%) not_optimized_instruction: 4,264,988 (17.0%) send_without_block_no_profiles: 882,357 ( 3.5%) send_not_optimized_method_type: 71,084 ( 0.3%) send_without_block_cfunc_array_variadic: 15,136 ( 0.1%) obj_to_string_not_string: 9,767 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 688,760): expandarray: 328,369 (47.7%) checkkeyword: 190,697 (27.7%) getclassvariable: 59,286 ( 8.6%) getblockparam: 49,119 ( 7.1%) invokesuperforward: 48,162 ( 7.0%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 840 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 3,642,051): register_spill_on_alloc: 3,420,578 (93.9%) register_spill_on_ccall: 221,473 ( 6.1%) Top-17 side exit reasons (100.0% of total 10,740,844): compile_error: 3,642,051 (33.9%) guard_type_failure: 2,624,731 (24.4%) guard_shape_failure: 1,902,123 (17.7%) unhandled_yarv_insn: 688,760 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 534,951 ( 5.0%) unhandled_kwarg: 455,354 ( 4.2%) unknown_newarray_send: 314,667 ( 2.9%) patchpoint_stable_constant_names: 227,790 ( 2.1%) unhandled_splat: 121,916 ( 1.1%) patchpoint_no_singleton_class: 108,465 ( 1.0%) unhandled_hir_insn: 76,397 ( 0.7%) patchpoint_method_redefined: 20,487 ( 0.2%) block_param_proxy_modified: 19,193 ( 0.2%) patchpoint_no_ep_escape: 3,765 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 16 ( 0.0%) send_count: 67,576,368 dynamic_send_count: 25,044,791 (37.1%) optimized_send_count: 42,531,577 (62.9%) iseq_optimized_send_count: 18,461,332 (27.3%) inline_cfunc_optimized_send_count: 13,154,471 (19.5%) non_variadic_cfunc_optimized_send_count: 8,243,438 (12.2%) variadic_cfunc_optimized_send_count: 2,672,336 ( 4.0%) dynamic_getivar_count: 7,322,001 dynamic_setivar_count: 7,230,445 compiled_iseq_count: 4,771 failed_iseq_count: 466 compile_time: 7,134ms profile_time: 52ms gc_time: 46ms invalidation_time: 123ms vm_write_pc_count: 63,337,758 vm_write_sp_count: 62,014,782 vm_write_locals_count: 62,014,782 vm_write_stack_count: 62,014,782 vm_write_to_parent_iseq_local_count: 292,458 vm_read_from_parent_iseq_local_count: 6,589,698 code_region_bytes: 22,724,608 side_exit_count: 10,740,844 total_insn_count: 515,656,824 vm_insn_count: 163,676,059 zjit_insn_count: 351,980,765 ratio_in_zjit: 68.3% ``` </details>
1 parent 0e5cb74 commit 0594646

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

zjit/src/cruby_methods.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ pub fn init() -> Annotations {
201201
annotate!(rb_cArray, "join", types::StringExact);
202202
annotate!(rb_cArray, "[]", inline_array_aref);
203203
annotate!(rb_cHash, "[]", inline_hash_aref);
204+
annotate!(rb_cHash, "size", types::Fixnum, no_gc, leaf, elidable);
204205
annotate!(rb_cHash, "empty?", types::BoolExact, no_gc, leaf, elidable);
205206
annotate!(rb_cNilClass, "nil?", types::TrueClass, no_gc, leaf, elidable);
206207
annotate!(rb_mKernel, "nil?", types::FalseClass, no_gc, leaf, elidable);

zjit/src/hir.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13390,4 +13390,61 @@ mod opt_tests {
1339013390
Return v13
1339113391
");
1339213392
}
13393+
13394+
#[test]
13395+
fn test_specialize_hash_size() {
13396+
eval("
13397+
def test(hash) = hash.size
13398+
test({foo: 3, bar: 1, baz: 4})
13399+
");
13400+
assert_snapshot!(hir_string("test"), @r"
13401+
fn test@<compiled>:2:
13402+
bb0():
13403+
EntryPoint interpreter
13404+
v1:BasicObject = LoadSelf
13405+
v2:BasicObject = GetLocal l0, SP@4
13406+
Jump bb2(v1, v2)
13407+
bb1(v5:BasicObject, v6:BasicObject):
13408+
EntryPoint JIT(0)
13409+
Jump bb2(v5, v6)
13410+
bb2(v8:BasicObject, v9:BasicObject):
13411+
PatchPoint MethodRedefined(Hash@0x1000, size@0x1008, cme:0x1010)
13412+
PatchPoint NoSingletonClass(Hash@0x1000)
13413+
v25:HashExact = GuardType v9, HashExact
13414+
IncrCounter inline_cfunc_optimized_send_count
13415+
v27:Fixnum = CCall size@0x1038, v25
13416+
CheckInterrupts
13417+
Return v27
13418+
");
13419+
}
13420+
13421+
#[test]
13422+
fn test_eliminate_hash_size() {
13423+
eval("
13424+
def test(hash)
13425+
hash.size
13426+
5
13427+
end
13428+
test({foo: 3, bar: 1, baz: 4})
13429+
");
13430+
assert_snapshot!(hir_string("test"), @r"
13431+
fn test@<compiled>:3:
13432+
bb0():
13433+
EntryPoint interpreter
13434+
v1:BasicObject = LoadSelf
13435+
v2:BasicObject = GetLocal l0, SP@4
13436+
Jump bb2(v1, v2)
13437+
bb1(v5:BasicObject, v6:BasicObject):
13438+
EntryPoint JIT(0)
13439+
Jump bb2(v5, v6)
13440+
bb2(v8:BasicObject, v9:BasicObject):
13441+
PatchPoint MethodRedefined(Hash@0x1000, size@0x1008, cme:0x1010)
13442+
PatchPoint NoSingletonClass(Hash@0x1000)
13443+
v28:HashExact = GuardType v9, HashExact
13444+
IncrCounter inline_cfunc_optimized_send_count
13445+
v19:Fixnum[5] = Const Value(5)
13446+
CheckInterrupts
13447+
Return v19
13448+
");
13449+
}
1339313450
}

0 commit comments

Comments
 (0)