Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YJIT: Handle rest+splat where non-splat < required #7499

Merged
merged 1 commit into from Mar 13, 2023

Conversation

jimmyhmiller
Copy link
Contributor

@jimmyhmiller jimmyhmiller commented Mar 10, 2023

Here are the stats of railsbench and liquid-render before and after these changes

Highlight here is railsbench

Before:
 iseq_has_rest_and_splat_fewer:     10,610 ( 3.3%)
After:
 n/a
Rails Bench Before
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                          block_arg:     64,789 (20.2%)
                        iseq_zsuper:     60,078 (18.7%)
            iseq_has_rest_and_block:     54,471 (17.0%)
                   iseq_arity_error:     30,685 ( 9.6%)
                iseq_ruby2_keywords:     25,058 ( 7.8%)
                     iseq_has_no_kw:     17,298 ( 5.4%)
          args_splat_cfunc_var_args:     16,295 ( 5.1%)
                           kw_splat:     12,997 ( 4.1%)
      iseq_has_rest_and_splat_fewer:     10,610 ( 3.3%)
                    iseq_has_kwrest:      7,319 ( 2.3%)
                  klass_megamorphic:      7,069 ( 2.2%)
           iseq_missing_optional_kw:      4,054 ( 1.3%)
               iseq_has_rest_and_kw:      2,183 ( 0.7%)
         iseq_has_rest_and_optional:      2,015 ( 0.6%)
             args_splat_cfunc_zuper:      2,002 ( 0.6%)
                      iseq_has_post:      1,988 ( 0.6%)
              cfunc_ruby_array_varg:      1,360 ( 0.4%)
                           keywords:        102 ( 0.0%)
    args_splat_cfunc_ruby2_keywords:         62 ( 0.0%)
                    args_splat_ivar:         50 ( 0.0%)
                      zsuper_method:         14 ( 0.0%)
                        send_getter:         12 ( 0.0%)
                args_splat_opt_call:          5 ( 0.0%)
        splatarray_length_not_equal:          2 ( 0.0%)
                    ivar_set_method:          2 ( 0.0%)
                  bmethod_block_arg:          2 ( 0.0%)
invokeblock exit reasons: 
      proc:      2,248 (92.7%)
    symbol:        176 ( 7.3%)
invokesuper exit reasons: 
    me_changed:      4,792 (68.6%)
         block:      2,194 (31.4%)
leave exit reasons: 
        interp_return:  1,754,442 (97.6%)
    start_pc_non_zero:     43,884 ( 2.4%)
         se_interrupt:         28 ( 0.0%)
getblockparamproxy exit reasons: 
    block_param_modified:          3 (100.0%)
getinstancevariable exit reasons:
    (all relevant counters are zero)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
            splat:      9,974 (99.8%)
    rhs_too_small:         23 ( 0.2%)
opt_getinlinecache exit reasons: 
    miss:         11 (100.0%)
invalidation reasons: 
       constant_ic_fill:      2,055 (58.1%)
          method_lookup:      1,140 (32.2%)
    constant_state_bump:        341 ( 9.6%)
num_send:                 13,804,774
num_send_known_class:        491,792 ( 3.6%)
num_send_polymorphic:      1,804,070 (13.1%)
iseq_stack_too_large:              0
iseq_too_long:                     0
bindings_allocations:            186
bindings_set:                      0
compiled_iseq_count:           9,297
compiled_block_count:         55,713
compiled_branch_count:        90,125
block_next_count:             15,333
defer_count:                  17,270
defer_empty_count:             2,838
freed_iseq_count:              4,058
invalidation_count:            3,536
constant_state_bumps:              0
get_ivar_max_depth:           10,068
inline_code_size:         10,302,980
outlined_code_size:       10,300,948
freed_code_size:                   0
code_region_size:         20,611,072
yjit_alloc_size:          16,436,061
live_context_size:         1,499,008
live_context_count:           53,536
live_page_count:               1,258
freed_page_count:                  0
code_gc_count:                     0
num_gc_obj_refs:              47,455
object_shape_count:            2,452
side_exit_count:             433,049
total_exit_count:          2,187,491
total_insns_count:        89,323,315
vm_insns_count:            7,751,075
yjit_insns_count:         82,005,289
ratio_in_yjit:                 91.3%
avg_len_in_yjit:                37.3
Top-20 most frequent exit ops (100.0% of exits):
               invokesuper:    105,390 (24.3%)
                      send:     98,084 (22.6%)
    opt_send_without_block:     92,015 (21.2%)
      opt_getconstant_path:     53,905 (12.4%)
               invokeblock:     31,108 ( 7.2%)
                  opt_aref:     14,088 ( 3.3%)
                     throw:     10,655 ( 2.5%)
               expandarray:      9,997 ( 2.3%)
             setlocal_WC_0:      8,401 ( 1.9%)
                    opt_eq:      4,991 ( 1.2%)
        getblockparamproxy:      2,271 ( 0.5%)
          putspecialobject:        729 ( 0.2%)
               objtostring:        432 ( 0.1%)
                 opt_nil_p:        313 ( 0.1%)
             definesmethod:        237 ( 0.1%)
                checkmatch:        205 ( 0.0%)
                      once:        104 ( 0.0%)
               opt_empty_p:         30 ( 0.0%)
                     leave:         29 ( 0.0%)
             setblockparam:         25 ( 0.0%)
Rails Bench After
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                          block_arg:     64,788 (20.3%)
                        iseq_zsuper:     60,077 (18.9%)
            iseq_has_rest_and_block:     54,470 (17.1%)
                   iseq_arity_error:     30,685 ( 9.6%)
                iseq_ruby2_keywords:     25,058 ( 7.9%)
                     iseq_has_no_kw:     17,298 ( 5.4%)
          args_splat_cfunc_var_args:     16,295 ( 5.1%)
                           kw_splat:     12,997 ( 4.1%)
         iseq_has_rest_and_optional:     10,626 ( 3.3%)
                    iseq_has_kwrest:      7,320 ( 2.3%)
                  klass_megamorphic:      7,068 ( 2.2%)
           iseq_missing_optional_kw:      4,054 ( 1.3%)
               iseq_has_rest_and_kw:      2,183 ( 0.7%)
             args_splat_cfunc_zuper:      2,002 ( 0.6%)
                      iseq_has_post:      1,988 ( 0.6%)
              cfunc_ruby_array_varg:      1,360 ( 0.4%)
                           keywords:        102 ( 0.0%)
    args_splat_cfunc_ruby2_keywords:         62 ( 0.0%)
                    args_splat_ivar:         50 ( 0.0%)
                      zsuper_method:         14 ( 0.0%)
                        send_getter:         12 ( 0.0%)
                args_splat_opt_call:          5 ( 0.0%)
                    ivar_set_method:          2 ( 0.0%)
                  bmethod_block_arg:          2 ( 0.0%)
        splatarray_length_not_equal:          2 ( 0.0%)
invokeblock exit reasons: 
      proc:      2,248 (92.7%)
    symbol:        176 ( 7.3%)
invokesuper exit reasons: 
    me_changed:      4,793 (68.6%)
         block:      2,194 (31.4%)
leave exit reasons: 
        interp_return:  1,754,414 (97.6%)
    start_pc_non_zero:     43,884 ( 2.4%)
         se_interrupt:         31 ( 0.0%)
getblockparamproxy exit reasons: 
    block_param_modified:          3 (100.0%)
getinstancevariable exit reasons:
    (all relevant counters are zero)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
            splat:      9,973 (99.8%)
    rhs_too_small:         23 ( 0.2%)
opt_getinlinecache exit reasons: 
    miss:         11 (100.0%)
invalidation reasons: 
       constant_ic_fill:      2,055 (58.1%)
          method_lookup:      1,144 (32.3%)
    constant_state_bump:        338 ( 9.6%)
num_send:                 13,818,721
num_send_known_class:        491,790 ( 3.6%)
num_send_polymorphic:      1,818,020 (13.2%)
iseq_stack_too_large:              0
iseq_too_long:                     0
bindings_allocations:            186
bindings_set:                      0
compiled_iseq_count:           9,297
compiled_block_count:         55,693
compiled_branch_count:        90,098
block_next_count:             15,334
defer_count:                  17,268
defer_empty_count:             2,839
freed_iseq_count:              4,058
invalidation_count:            3,537
constant_state_bumps:              0
get_ivar_max_depth:           10,069
inline_code_size:         10,303,984
outlined_code_size:       10,301,888
freed_code_size:                   0
code_region_size:         20,611,072
yjit_alloc_size:          16,437,457
live_context_size:         1,498,560
live_context_count:           53,520
live_page_count:               1,258
freed_page_count:                  0
code_gc_count:                     0
num_gc_obj_refs:              47,443
object_shape_count:            2,452
side_exit_count:             431,055
total_exit_count:          2,185,469
total_insns_count:        89,524,957
vm_insns_count:            7,749,203
yjit_insns_count:         82,206,809
ratio_in_yjit:                 91.3%
avg_len_in_yjit:                37.4
Top-20 most frequent exit ops (100.0% of exits):
               invokesuper:    105,392 (24.4%)
                      send:     98,083 (22.8%)
    opt_send_without_block:     90,019 (20.9%)
      opt_getconstant_path:     53,906 (12.5%)
               invokeblock:     31,108 ( 7.2%)
                  opt_aref:     14,086 ( 3.3%)
                     throw:     10,655 ( 2.5%)
               expandarray:      9,996 ( 2.3%)
             setlocal_WC_0:      8,401 ( 1.9%)
                    opt_eq:      4,990 ( 1.2%)
        getblockparamproxy:      2,271 ( 0.5%)
          putspecialobject:        729 ( 0.2%)
               objtostring:        430 ( 0.1%)
                 opt_nil_p:        313 ( 0.1%)
             definesmethod:        237 ( 0.1%)
                checkmatch:        204 ( 0.0%)
                      once:        104 ( 0.0%)
                     leave:         32 ( 0.0%)
               opt_empty_p:         30 ( 0.0%)
             setblockparam:         25 ( 0.0%)
Liquid Render Before
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                    block_arg:      1,470 (60.8%)
                zsuper_method:        832 (34.4%)
        cfunc_ruby_array_varg:         35 ( 1.4%)
            klass_megamorphic:         32 ( 1.3%)
         iseq_has_rest_and_kw:         14 ( 0.6%)
                  send_getter:         12 ( 0.5%)
     iseq_missing_optional_kw:          9 ( 0.4%)
    args_splat_cfunc_var_args:          8 ( 0.3%)
                     kw_splat:          3 ( 0.1%)
      iseq_has_rest_and_block:          1 ( 0.0%)
              ivar_set_method:          1 ( 0.0%)
invokeblock exit reasons: 
      proc:        344 (81.3%)
    symbol:         79 (18.7%)
invokesuper exit reasons: 
    block:         81 (100.0%)
leave exit reasons: 
        interp_return:    275,761 (100.0%)
    start_pc_non_zero:        110 ( 0.0%)
         se_interrupt:          9 ( 0.0%)
getblockparamproxy exit reasons: 
    (all relevant counters are zero)
getinstancevariable exit reasons:
    (all relevant counters are zero)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
    rhs_too_small:         10 (100.0%)
opt_getinlinecache exit reasons: 
    (all relevant counters are zero)
invalidation reasons: 
       constant_ic_fill:        583 (81.7%)
    constant_state_bump:         91 (12.7%)
          method_lookup:         40 ( 5.6%)
num_send:                  3,024,118
num_send_known_class:        135,743 ( 4.5%)
num_send_polymorphic:        584,808 (19.3%)
iseq_stack_too_large:              0
iseq_too_long:                     0
bindings_allocations:            152
bindings_set:                      0
compiled_iseq_count:           1,689
compiled_block_count:         11,963
compiled_branch_count:        19,756
block_next_count:              4,219
defer_count:                   3,900
defer_empty_count:               773
freed_iseq_count:                560
invalidation_count:              714
constant_state_bumps:              0
get_ivar_max_depth:               10
inline_code_size:          1,998,512
outlined_code_size:        1,995,712
freed_code_size:                   0
code_region_size:          3,997,696
yjit_alloc_size:           5,496,381
live_context_size:           514,248
live_context_count:           18,366
live_page_count:                 244
freed_page_count:                  0
code_gc_count:                     0
num_gc_obj_refs:               7,955
object_shape_count:              770
side_exit_count:              23,050
total_exit_count:            298,811
total_insns_count:        20,332,079
vm_insns_count:            2,298,855
yjit_insns_count:         18,056,274
ratio_in_yjit:                 88.7%
avg_len_in_yjit:                60.3
Top-17 most frequent exit ops (100.0% of exits):
                     throw:     19,105 (82.9%)
                      send:      1,493 ( 6.5%)
    opt_send_without_block:        924 ( 4.0%)
      opt_getconstant_path:        751 ( 3.3%)
               invokeblock:        423 ( 1.8%)
                    opt_eq:         89 ( 0.4%)
                      once:         87 ( 0.4%)
               invokesuper:         82 ( 0.4%)
          putspecialobject:         37 ( 0.2%)
             setlocal_WC_0:         12 ( 0.1%)
        getblockparamproxy:         11 ( 0.0%)
               expandarray:         10 ( 0.0%)
                  opt_aref:         10 ( 0.0%)
                     leave:          9 ( 0.0%)
                opt_length:          3 ( 0.0%)
                checkmatch:          2 ( 0.0%)
                  opt_ltlt:          2 ( 0.0%)
Liquid Render After
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                    block_arg:      1,470 (60.8%)
                zsuper_method:        832 (34.4%)
        cfunc_ruby_array_varg:         35 ( 1.4%)
            klass_megamorphic:         32 ( 1.3%)
         iseq_has_rest_and_kw:         14 ( 0.6%)
                  send_getter:         12 ( 0.5%)
     iseq_missing_optional_kw:          9 ( 0.4%)
    args_splat_cfunc_var_args:          8 ( 0.3%)
                     kw_splat:          3 ( 0.1%)
      iseq_has_rest_and_block:          1 ( 0.0%)
              ivar_set_method:          1 ( 0.0%)
invokeblock exit reasons: 
      proc:        344 (81.3%)
    symbol:         79 (18.7%)
invokesuper exit reasons: 
    block:         81 (100.0%)
leave exit reasons: 
        interp_return:    275,783 (100.0%)
    start_pc_non_zero:        110 ( 0.0%)
         se_interrupt:         15 ( 0.0%)
getblockparamproxy exit reasons: 
    (all relevant counters are zero)
getinstancevariable exit reasons:
    (all relevant counters are zero)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
    rhs_too_small:         10 (100.0%)
opt_getinlinecache exit reasons: 
    (all relevant counters are zero)
invalidation reasons: 
       constant_ic_fill:        583 (81.7%)
    constant_state_bump:         91 (12.7%)
          method_lookup:         40 ( 5.6%)
num_send:                  3,023,933
num_send_known_class:        135,728 ( 4.5%)
num_send_polymorphic:        584,785 (19.3%)
iseq_stack_too_large:              0
iseq_too_long:                     0
bindings_allocations:            152
bindings_set:                      0
compiled_iseq_count:           1,689
compiled_block_count:         11,964
compiled_branch_count:        19,751
block_next_count:              4,220
defer_count:                   3,900
defer_empty_count:               773
freed_iseq_count:                560
invalidation_count:              714
constant_state_bumps:              0
get_ivar_max_depth:               10
inline_code_size:          1,999,512
outlined_code_size:        1,999,216
freed_code_size:                   0
code_region_size:          4,014,080
yjit_alloc_size:           5,497,073
live_context_size:           514,276
live_context_count:           18,367
live_page_count:                 245
freed_page_count:                  0
code_gc_count:                     0
num_gc_obj_refs:               7,956
object_shape_count:              770
side_exit_count:              23,056
total_exit_count:            298,839
total_insns_count:        20,331,889
vm_insns_count:            2,299,558
yjit_insns_count:         18,055,387
ratio_in_yjit:                 88.7%
avg_len_in_yjit:                60.3
Top-16 most frequent exit ops (100.0% of exits):
                     throw:     19,105 (82.9%)
                      send:      1,491 ( 6.5%)
    opt_send_without_block:        928 ( 4.0%)
      opt_getconstant_path:        751 ( 3.3%)
               invokeblock:        423 ( 1.8%)
                    opt_eq:         89 ( 0.4%)
                      once:         87 ( 0.4%)
               invokesuper:         82 ( 0.4%)
          putspecialobject:         37 ( 0.2%)
                     leave:         15 ( 0.1%)
             setlocal_WC_0:         12 ( 0.1%)
        getblockparamproxy:         11 ( 0.0%)
               expandarray:         10 ( 0.0%)
                  opt_aref:         10 ( 0.0%)
                  opt_ltlt:          3 ( 0.0%)
                checkmatch:          2 ( 0.0%)

@matzbot matzbot requested a review from a team March 10, 2023 20:10
@maximecb maximecb merged commit 45127c8 into ruby:master Mar 13, 2023
98 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants