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 splat with opt more fully #7209

Merged
merged 2 commits into from
Jan 31, 2023

Conversation

jimmyhmiller
Copy link
Contributor

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

Highlights:

Rails bench:

Before:
splatarray_length_not_equal       2029 ( 0.6%)

After:
splatarray_length_not_equal          2 ( 0.0%)

Liquid render:

Before:
splatarray_length_not_equal       2979 ( 6.4%)
After:
None
Rails Bench Before
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                      iseq_has_rest     110946 (33.8%)
                          block_arg      64643 (19.7%)
                        iseq_zsuper      46081 (14.0%)
                iseq_ruby2_keywords      24994 ( 7.6%)
                   iseq_arity_error      19401 ( 5.9%)
          args_splat_cfunc_var_args      16250 ( 4.9%)
                     iseq_has_no_kw      15970 ( 4.9%)
                           kw_splat      12995 ( 4.0%)
                    iseq_has_kwrest       5294 ( 1.6%)
           iseq_missing_optional_kw       4054 ( 1.2%)
        splatarray_length_not_equal       2029 ( 0.6%)
             args_splat_cfunc_zuper       2002 ( 0.6%)
                      iseq_has_post       1987 ( 0.6%)
                     refined_method        891 ( 0.3%)
              cfunc_ruby_array_varg        653 ( 0.2%)
                           keywords        102 ( 0.0%)
    args_splat_cfunc_ruby2_keywords         62 ( 0.0%)
                    args_splat_ivar         49 ( 0.0%)
                        send_getter         12 ( 0.0%)
                      zsuper_method          9 ( 0.0%)
                args_splat_opt_call          5 ( 0.0%)
                  bmethod_block_arg          2 ( 0.0%)
                    ivar_set_method          1 ( 0.0%)
invokeblock exit reasons: 
                  proc     115212 (90.9%)
                 ifunc       5897 ( 4.7%)
    iseq_block_changed       2463 ( 1.9%)
       iseq_arg0_splat       2000 ( 1.6%)
      iseq_tag_changed       1153 ( 0.9%)
                symbol         68 ( 0.1%)
invokesuper exit reasons: 
         block       4850 (98.4%)
    me_changed         80 ( 1.6%)
leave exit reasons: 
        interp_return    1837165 (97.7%)
    start_pc_non_zero      43883 ( 2.3%)
         se_interrupt         32 ( 0.0%)
getblockparamproxy exit reasons: 
    block_param_modified          3 (100.0%)
getinstancevariable exit reasons:
    megamorphic      10302 (100.0%)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
            splat       9974 (99.8%)
    rhs_too_small         22 ( 0.2%)
opt_getinlinecache exit reasons: 
    miss         11 (100.0%)
invalidation reasons: 
       constant_ic_fill       2011 (59.2%)
          method_lookup       1045 (30.8%)
    constant_state_bump        339 (10.0%)
bindings_allocations:         184
bindings_set:                   0
compiled_iseq_count:         9291
compiled_block_count:       51556
compiled_branch_count:      81930
block_next_count:           14966
defer_count:                16167
freed_iseq_count:            4064
invalidation_count:          3395
constant_state_bumps:           0
inline_code_size:         8761368
outlined_code_size:       8760932
freed_code_size:                0
code_region_size:        17580032
yjit_alloc_size:         97526573
live_page_count:             1073
freed_page_count:               0
code_gc_count:                  0
num_gc_obj_refs:            41145
object_shape_count:          2397
side_exit_count:           616130
total_exit_count:         2453295
total_insns_count:       95024544
vm_insns_count:          11833218
yjit_insns_count:        83807456
ratio_in_yjit:              87.5%
avg_len_in_yjit:             33.9
Top-20 most frequent exit ops (100.0% of exits):
    opt_send_without_block:     144864 (23.5%)
               invokeblock:     144171 (23.4%)
               invokesuper:     117072 (19.0%)
                      send:     104047 (16.9%)
      opt_getconstant_path:      53736 (8.7%)
                  opt_aref:      14088 (2.3%)
                     throw:      10587 (1.7%)
               expandarray:       9996 (1.6%)
             setlocal_WC_0:       8357 (1.4%)
                    opt_eq:       5009 (0.8%)
        getblockparamproxy:       2271 (0.4%)
               objtostring:        448 (0.1%)
          putspecialobject:        386 (0.1%)
                 opt_nil_p:        327 (0.1%)
             definesmethod:        240 (0.0%)
                checkmatch:        204 (0.0%)
                      once:        104 (0.0%)
       getinstancevariable:        102 (0.0%)
                     leave:         33 (0.0%)
               opt_empty_p:         32 (0.0%)
Rails Bench After
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                      iseq_has_rest     110946 (34.0%)
                          block_arg      64645 (19.8%)
                        iseq_zsuper      46081 (14.1%)
                iseq_ruby2_keywords      24994 ( 7.7%)
                   iseq_arity_error      19401 ( 5.9%)
          args_splat_cfunc_var_args      16251 ( 5.0%)
                     iseq_has_no_kw      15971 ( 4.9%)
                           kw_splat      12995 ( 4.0%)
                    iseq_has_kwrest       5294 ( 1.6%)
           iseq_missing_optional_kw       4054 ( 1.2%)
             args_splat_cfunc_zuper       2002 ( 0.6%)
                      iseq_has_post       1987 ( 0.6%)
                     refined_method        891 ( 0.3%)
              cfunc_ruby_array_varg        653 ( 0.2%)
                           keywords        102 ( 0.0%)
    args_splat_cfunc_ruby2_keywords         62 ( 0.0%)
                    args_splat_ivar         49 ( 0.0%)
                        send_getter         12 ( 0.0%)
                      zsuper_method          9 ( 0.0%)
                args_splat_opt_call          5 ( 0.0%)
        splatarray_length_not_equal          2 ( 0.0%)
                  bmethod_block_arg          2 ( 0.0%)
                    ivar_set_method          1 ( 0.0%)
invokeblock exit reasons: 
                  proc     115214 (90.9%)
                 ifunc       5896 ( 4.6%)
    iseq_block_changed       2463 ( 1.9%)
       iseq_arg0_splat       2000 ( 1.6%)
      iseq_tag_changed       1155 ( 0.9%)
                symbol         68 ( 0.1%)
invokesuper exit reasons: 
         block       4850 (98.4%)
    me_changed         80 ( 1.6%)
leave exit reasons: 
        interp_return    1832617 (97.7%)
    start_pc_non_zero      43882 ( 2.3%)
         se_interrupt         31 ( 0.0%)
getblockparamproxy exit reasons: 
    block_param_modified          3 (100.0%)
getinstancevariable exit reasons:
    megamorphic      10302 (100.0%)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
            splat       9974 (99.8%)
    rhs_too_small         22 ( 0.2%)
opt_getinlinecache exit reasons: 
    miss         11 (100.0%)
invalidation reasons: 
       constant_ic_fill       2008 (59.2%)
          method_lookup       1045 (30.8%)
    constant_state_bump        341 (10.0%)
bindings_allocations:         184
bindings_set:                   0
compiled_iseq_count:         9291
compiled_block_count:       51521
compiled_branch_count:      81854
block_next_count:           14958
defer_count:                16151
freed_iseq_count:            4064
invalidation_count:          3394
constant_state_bumps:           0
inline_code_size:         8767716
outlined_code_size:       8764516
freed_code_size:                0
code_region_size:        17580032
yjit_alloc_size:         97597423
live_page_count:             1073
freed_page_count:               0
code_gc_count:                  0
num_gc_obj_refs:            41221
object_shape_count:          2396
side_exit_count:           614120
total_exit_count:         2446737
total_insns_count:       95010644
vm_insns_count:          11815839
yjit_insns_count:        83808925
ratio_in_yjit:              87.6%
avg_len_in_yjit:             34.0
Top-20 most frequent exit ops (100.0% of exits):
    opt_send_without_block:     144844 (23.6%)
               invokeblock:     144173 (23.5%)
               invokesuper:     117058 (19.1%)
                      send:     102048 (16.6%)
      opt_getconstant_path:      53763 (8.8%)
                  opt_aref:      14089 (2.3%)
                     throw:      10587 (1.7%)
               expandarray:       9996 (1.6%)
             setlocal_WC_0:       8358 (1.4%)
                    opt_eq:       5009 (0.8%)
        getblockparamproxy:       2271 (0.4%)
               objtostring:        449 (0.1%)
          putspecialobject:        386 (0.1%)
                 opt_nil_p:        327 (0.1%)
             definesmethod:        240 (0.0%)
                checkmatch:        204 (0.0%)
                      once:        104 (0.0%)
       getinstancevariable:        102 (0.0%)
                     leave:         32 (0.0%)
               opt_empty_p:         32 (0.0%)
Liquid Render Before
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                  iseq_has_rest      41227 (88.8%)
    splatarray_length_not_equal       2979 ( 6.4%)
                      block_arg       1323 ( 2.9%)
                  zsuper_method        792 ( 1.7%)
       iseq_missing_optional_kw         39 ( 0.1%)
          cfunc_ruby_array_varg         39 ( 0.1%)
      args_splat_cfunc_var_args         11 ( 0.0%)
invokeblock exit reasons: 
    iseq_block_changed      26318 (94.7%)
      iseq_tag_changed       1366 ( 4.9%)
                  proc         90 ( 0.3%)
                 ifunc         10 ( 0.0%)
invokesuper exit reasons: 
    block          5 (100.0%)
leave exit reasons: 
        interp_return     329111 (100.0%)
    start_pc_non_zero        105 ( 0.0%)
         se_interrupt         13 ( 0.0%)
getblockparamproxy exit reasons: 
    (all relevant counters are zero)
getinstancevariable exit reasons:
    megamorphic          8 (100.0%)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
    (all relevant counters are zero)
opt_getinlinecache exit reasons: 
    (all relevant counters are zero)
invalidation reasons: 
       constant_ic_fill        149 (83.2%)
    constant_state_bump         20 (11.2%)
          method_lookup         10 ( 5.6%)
bindings_allocations:          77
bindings_set:                   0
compiled_iseq_count:          695
compiled_block_count:        5923
compiled_branch_count:       9897
block_next_count:            2048
defer_count:                 1990
freed_iseq_count:             173
invalidation_count:           179
constant_state_bumps:           0
inline_code_size:          937356
outlined_code_size:        934812
freed_code_size:                0
code_region_size:         1884160
yjit_alloc_size:         12276093
live_page_count:              115
freed_page_count:               0
code_gc_count:                  0
num_gc_obj_refs:             4016
object_shape_count:           539
side_exit_count:            96193
total_exit_count:          425304
total_insns_count:       22130540
vm_insns_count:           4087260
yjit_insns_count:        18139473
ratio_in_yjit:              81.5%
avg_len_in_yjit:             42.4
Top-12 most frequent exit ops (100.0% of exits):
    opt_send_without_block:      45343 (47.1%)
               invokeblock:      27784 (28.9%)
                     throw:      21115 (22.0%)
                      send:       1325 (1.4%)
      opt_getconstant_path:        372 (0.4%)
               invokesuper:        125 (0.1%)
                    opt_eq:         87 (0.1%)
                     leave:         13 (0.0%)
                      once:         12 (0.0%)
          putspecialobject:         12 (0.0%)
                  opt_ltlt:          3 (0.0%)
                opt_length:          2 (0.0%)
Liquid Render After
         ***YJIT: Printing YJIT statistics on exit***
method call exit reasons: 
                iseq_has_rest      41226 (94.9%)
                    block_arg       1324 ( 3.0%)
                zsuper_method        792 ( 1.8%)
     iseq_missing_optional_kw         39 ( 0.1%)
        cfunc_ruby_array_varg         39 ( 0.1%)
    args_splat_cfunc_var_args         11 ( 0.0%)
invokeblock exit reasons: 
    iseq_block_changed      26318 (94.7%)
      iseq_tag_changed       1367 ( 4.9%)
                  proc         90 ( 0.3%)
                 ifunc         10 ( 0.0%)
invokesuper exit reasons: 
    block          5 (100.0%)
leave exit reasons: 
        interp_return     329117 (100.0%)
    start_pc_non_zero        105 ( 0.0%)
         se_interrupt         16 ( 0.0%)
getblockparamproxy exit reasons: 
    (all relevant counters are zero)
getinstancevariable exit reasons:
    megamorphic          8 (100.0%)
setinstancevariable exit reasons:
    (all relevant counters are zero)
opt_aref exit reasons: 
    (all relevant counters are zero)
expandarray exit reasons: 
    (all relevant counters are zero)
opt_getinlinecache exit reasons: 
    (all relevant counters are zero)
invalidation reasons: 
       constant_ic_fill        149 (83.2%)
    constant_state_bump         20 (11.2%)
          method_lookup         10 ( 5.6%)
bindings_allocations:          77
bindings_set:                   0
compiled_iseq_count:          696
compiled_block_count:        5907
compiled_branch_count:       9893
block_next_count:            2044
defer_count:                 1983
freed_iseq_count:             173
invalidation_count:           179
constant_state_bumps:           0
inline_code_size:          935820
outlined_code_size:        934264
freed_code_size:                0
code_region_size:         1884160
yjit_alloc_size:         12257324
live_page_count:              115
freed_page_count:               0
code_gc_count:                  0
num_gc_obj_refs:             4006
object_shape_count:           538
side_exit_count:            93216
total_exit_count:          422333
total_insns_count:       22111919
vm_insns_count:           4075284
yjit_insns_count:        18129851
ratio_in_yjit:              81.6%
avg_len_in_yjit:             42.7
Top-13 most frequent exit ops (100.0% of exits):
    opt_send_without_block:      42362 (45.4%)
               invokeblock:      27785 (29.8%)
                     throw:      21115 (22.7%)
                      send:       1325 (1.4%)
      opt_getconstant_path:        372 (0.4%)
               invokesuper:        125 (0.1%)
                    opt_eq:         87 (0.1%)
                     leave:         16 (0.0%)
                      once:         12 (0.0%)
          putspecialobject:         12 (0.0%)
                  opt_ltlt:          3 (0.0%)
                   opt_div:          1 (0.0%)
                  opt_aref:          1 (0.0%)

@k0kubun k0kubun requested a review from a team January 31, 2023 17:11
yjit.c Outdated Show resolved Hide resolved
yjit/src/codegen.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@maximecb maximecb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems there's a test failing

yjit/src/codegen.rs Outdated Show resolved Hide resolved
@k0kubun
Copy link
Member

k0kubun commented Jan 31, 2023

Seems there's a test failing

The first commit in this branch failed with BorrowMutError, but that's what #7212 fixed. It should be fine now.

@maximecb maximecb merged commit 1148fab into ruby:master Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants