summaryrefslogtreecommitdiff
path: root/sample/trick2025
diff options
context:
space:
mode:
authorNozomi Hijikata <121233810+nozomemein@users.noreply.github.com>2026-06-03 22:42:20 +0900
committerGitHub <noreply@github.com>2026-06-03 09:42:20 -0400
commitf717edca05fa42e122b7fb8148aa6a728b3aa582 (patch)
tree2a8910e56b7ea8b362eb64a8c6c597408d91ddcd /sample/trick2025
parent464e5665a4b02760196867406f1291261ea08fbe (diff)
ZJIT: Implement Polymorphic DefinedIvar (#16981)HEADmaster
* ZJIT: Implement Polymorphic Definedivar Closes: https://github.com/Shopify/ruby/issues/980 Build polymorphic shape/type branches for definedivar in HIR. For each profiled T_OBJECT shape, specialize defined?(`@ivar`) to a constant pushval or nil based on the compile-time ivar index check. DefinedIvar already profiles self on monomorphic shape guard failures for recompilation, so the recompiled HIR can use the collected polymorphic shapes while keeping a generic DefinedIvar fallback for misses and unsupported shapes. ## Benchmark ### lobsters Summary: ```diff - dynamic_definedivar_count: 1,294,854 ( 0.7%) + dynamic_definedivar_count: 503,058 ( 0.3%) ratio_in_zjit: 88.4% ``` ``` zjit-master: ruby 4.1.0dev (2026-05-23T00:08:49Z master 5855d61ee4) +ZJIT stats +PRISM [arm64-darwin25] zjit-polymorphic-definedivar: ruby 4.1.0dev (2026-05-23T07:11:22Z zjit-polymorphic-d.. f75a82e7f1) +ZJIT stats +PRISM [arm64-darwin25] last_commit=ZJIT: Implement Polymorphic Definedivar -------- ---------------- --------------------------------- ------------------------------------ ---------------------------------------- bench zjit-master (ms) zjit-polymorphic-definedivar (ms) zjit-polymorphic-definedivar 1st itr zjit-master/zjit-polymorphic-definedivar lobsters 529.9 ± 3.6% 504.2 ± 7.7% 1.148 1.051 -------- ---------------- --------------------------------- ------------------------------------ ---------------------------------------- ``` Full stats details below: <details> <summary>before patch</summary> ``` Top-2 not optimized method types for send (100.0% of total 65,120): null: 44,877 (68.9%) optimized: 20,243 (31.1%) Top-3 not optimized method types for send_without_block (100.0% of total 716,678): optimized_send: 711,905 (99.3%) optimized_block_call: 4,299 ( 0.6%) zsuper: 474 ( 0.1%) Top-1 not optimized method types for super (100.0% of total 3,678): attrset: 3,678 (100.0%) Top-1 instructions with uncategorized fallback reason (100.0% of total 65,868): opt_send_without_block: 65,868 (100.0%) Top-20 send fallback reasons (99.5% of total 22,386,632): invokeblock_not_specialized: 5,946,612 (26.6%) one_or_more_complex_arg_pass: 4,376,419 (19.5%) send_without_block_polymorphic: 3,748,855 (16.7%) send_without_block_no_profiles: 2,830,116 (12.6%) send_without_block_megamorphic: 1,108,467 ( 5.0%) sendforward_not_specialized: 971,957 ( 4.3%) send_polymorphic: 806,862 ( 3.6%) send_without_block_not_optimized_method_type_optimized: 716,204 ( 3.2%) super_polymorphic: 337,181 ( 1.5%) too_many_args_for_lir: 333,633 ( 1.5%) send_not_optimized_need_permission: 238,842 ( 1.1%) send_without_block_not_optimized_need_permission: 180,946 ( 0.8%) send_no_profiles: 177,008 ( 0.8%) argc_param_mismatch: 124,061 ( 0.6%) super_complex_args_pass: 89,280 ( 0.4%) invokesuperforward_not_specialized: 80,729 ( 0.4%) uncategorized: 65,868 ( 0.3%) send_not_optimized_method_type: 65,120 ( 0.3%) super_from_block: 43,185 ( 0.2%) obj_to_string_not_string: 42,731 ( 0.2%) Top-4 setivar fallback reasons (100.0% of total 4,182,333): not_monomorphic: 3,969,254 (94.9%) not_t_object: 119,505 ( 2.9%) complex: 93,131 ( 2.2%) new_shape_needs_extension: 443 ( 0.0%) Top-2 getivar fallback reasons (100.0% of total 11,716,846): not_monomorphic: 11,537,525 (98.5%) complex: 179,321 ( 1.5%) Top-3 definedivar fallback reasons (100.0% of total 1,294,854): not_monomorphic: 1,289,423 (99.6%) complex: 5,122 ( 0.4%) not_t_object: 309 ( 0.0%) Top-5 invokeblock handler (100.0% of total 6,968,323): monomorphic_ifunc: 4,143,418 (59.5%) monomorphic_other: 1,444,525 (20.7%) monomorphic_iseq: 865,749 (12.4%) polymorphic: 508,677 ( 7.3%) megamorphic: 5,954 ( 0.1%) Top-6 getblockparamproxy handler (100.0% of total 3,321,873): polymorphic: 2,370,458 (71.4%) nil: 492,185 (14.8%) iseq: 242,627 ( 7.3%) no_profiles: 168,826 ( 5.1%) proc: 40,245 ( 1.2%) megamorphic: 7,532 ( 0.2%) Top-7 popular complex argument-parameter features not optimized (100.0% of total 4,677,994): caller_blockarg: 3,092,361 (66.1%) param_forwardable: 697,044 (14.9%) param_rest: 409,311 ( 8.7%) caller_kwarg: 193,462 ( 4.1%) param_kwrest: 143,181 ( 3.1%) caller_kw_splat: 85,992 ( 1.8%) caller_splat: 56,643 ( 1.2%) Top-3 compile error reasons (100.0% of total 196,397): exception_handler: 192,000 (97.8%) native_stack_too_large: 4,342 ( 2.2%) validation_mismatched_block_arity: 55 ( 0.0%) Top-2 unhandled HIR insns (100.0% of total 229,881): throw: 194,104 (84.4%) invokebuiltin: 35,777 (15.6%) Top-19 side exit reasons (100.0% of total 8,637,525): guard_type_failure: 7,692,359 (89.1%) unhandled_hir_insn: 229,881 ( 2.7%) compile_error: 196,397 ( 2.3%) patchpoint_method_redefined: 118,680 ( 1.4%) block_param_proxy_fallback_miss: 112,551 ( 1.3%) no_profile_send: 93,334 ( 1.1%) block_param_proxy_not_nil: 75,195 ( 0.9%) patchpoint_stable_constant_names: 55,819 ( 0.6%) patchpoint_no_singleton_class: 19,352 ( 0.2%) unhandled_block_arg: 14,541 ( 0.2%) block_param_proxy_not_iseq_or_ifunc: 13,401 ( 0.2%) fixnum_lshift_overflow: 10,165 ( 0.1%) guard_less_failure: 3,120 ( 0.0%) guard_shape_failure: 1,302 ( 0.0%) guard_greater_eq_failure: 941 ( 0.0%) guard_super_method_entry: 407 ( 0.0%) interrupt: 49 ( 0.0%) obj_to_string_fallback: 30 ( 0.0%) guard_not_shared_failure: 1 ( 0.0%) send_count: 182,469,185 dynamic_send_count: 22,386,632 (12.3%) optimized_send_count: 160,082,553 (87.7%) dynamic_setivar_count: 4,182,333 ( 2.3%) dynamic_getivar_count: 11,716,846 ( 6.4%) dynamic_definedivar_count: 1,294,854 ( 0.7%) iseq_optimized_send_count: 54,154,353 (29.7%) inline_cfunc_optimized_send_count: 74,812,159 (41.0%) inline_iseq_optimized_send_count: 6,346,705 ( 3.5%) non_variadic_cfunc_optimized_send_count: 13,789,249 ( 7.6%) variadic_cfunc_optimized_send_count: 10,980,087 ( 6.0%) compiled_iseq_count: 6,166 compiled_side_exit_count: 80,485 failed_iseq_count: 3 compile_time: 2,462ms compile_side_exit_time: 113ms compile_side_exit_time_ratio: 4.6% compile_hir_time: 798ms compile_hir_build_time: 238ms compile_hir_strength_reduce_time: 322ms compile_hir_canonicalize_time: 49ms compile_hir_fold_constants_time: 37ms compile_hir_clean_cfg_time: 26ms compile_hir_eliminate_dead_code_time: 30ms compile_lir_time: 1,525ms profile_time: 39ms gc_time: 33ms invalidation_time: 14ms vm_write_jit_frame_count: 137,433,269 vm_write_sp_count: 137,433,269 vm_write_locals_count: 131,272,119 vm_write_stack_count: 131,272,119 vm_write_to_parent_iseq_local_count: 688,492 guard_type_count: 145,711,992 guard_type_exit_ratio: 5.3% guard_shape_count: 36,890,099 guard_shape_exit_ratio: 0.0% load_field_count: 210,155,590 store_field_count: 15,758,742 side_exit_size: 13,563,708 code_region_bytes: 33,505,280 side_exit_size_ratio: 40.5% zjit_alloc_bytes: 22,783,024 total_mem_bytes: 56,288,304 side_exit_count: 8,637,525 total_insn_count: 995,180,861 vm_insn_count: 115,515,525 zjit_insn_count: 879,665,336 ratio_in_zjit: 88.4% ``` </details> <details> <summary>after patch</summary> ``` Top-2 not optimized method types for send (100.0% of total 65,119): null: 44,877 (68.9%) optimized: 20,242 (31.1%) Top-3 not optimized method types for send_without_block (100.0% of total 716,636): optimized_send: 711,869 (99.3%) optimized_block_call: 4,293 ( 0.6%) zsuper: 474 ( 0.1%) Top-1 not optimized method types for super (100.0% of total 3,676): attrset: 3,676 (100.0%) Top-1 instructions with uncategorized fallback reason (100.0% of total 65,866): opt_send_without_block: 65,866 (100.0%) Top-20 send fallback reasons (99.5% of total 22,409,237): invokeblock_not_specialized: 5,946,405 (26.5%) one_or_more_complex_arg_pass: 4,376,457 (19.5%) send_without_block_polymorphic: 3,775,975 (16.9%) send_without_block_no_profiles: 2,830,029 (12.6%) send_without_block_megamorphic: 1,104,527 ( 4.9%) sendforward_not_specialized: 971,924 ( 4.3%) send_polymorphic: 806,852 ( 3.6%) send_without_block_not_optimized_method_type_optimized: 716,162 ( 3.2%) super_polymorphic: 337,178 ( 1.5%) too_many_args_for_lir: 333,625 ( 1.5%) send_not_optimized_need_permission: 238,842 ( 1.1%) send_without_block_not_optimized_need_permission: 180,949 ( 0.8%) send_no_profiles: 176,799 ( 0.8%) argc_param_mismatch: 124,064 ( 0.6%) super_complex_args_pass: 89,280 ( 0.4%) invokesuperforward_not_specialized: 80,723 ( 0.4%) uncategorized: 65,866 ( 0.3%) send_not_optimized_method_type: 65,119 ( 0.3%) super_from_block: 43,182 ( 0.2%) obj_to_string_not_string: 42,725 ( 0.2%) Top-4 setivar fallback reasons (100.0% of total 4,182,216): not_monomorphic: 3,969,159 (94.9%) not_t_object: 119,484 ( 2.9%) complex: 93,131 ( 2.2%) new_shape_needs_extension: 442 ( 0.0%) Top-2 getivar fallback reasons (100.0% of total 11,716,471): not_monomorphic: 11,537,150 (98.5%) complex: 179,321 ( 1.5%) Top-3 definedivar fallback reasons (100.0% of total 503,058): not_monomorphic: 498,173 (99.0%) complex: 4,576 ( 0.9%) not_t_object: 309 ( 0.1%) Top-5 invokeblock handler (100.0% of total 6,968,099): monomorphic_ifunc: 4,143,324 (59.5%) monomorphic_other: 1,444,457 (20.7%) monomorphic_iseq: 865,705 (12.4%) polymorphic: 508,659 ( 7.3%) megamorphic: 5,954 ( 0.1%) Top-6 getblockparamproxy handler (100.0% of total 3,321,803): polymorphic: 2,370,425 (71.4%) nil: 492,172 (14.8%) iseq: 242,810 ( 7.3%) no_profiles: 168,625 ( 5.1%) proc: 40,239 ( 1.2%) megamorphic: 7,532 ( 0.2%) Top-7 popular complex argument-parameter features not optimized (100.0% of total 4,678,011): caller_blockarg: 3,092,480 (66.1%) param_forwardable: 697,011 (14.9%) param_rest: 409,285 ( 8.7%) caller_kwarg: 193,450 ( 4.1%) param_kwrest: 143,179 ( 3.1%) caller_kw_splat: 85,971 ( 1.8%) caller_splat: 56,635 ( 1.2%) Top-3 compile error reasons (100.0% of total 196,386): exception_handler: 191,989 (97.8%) native_stack_too_large: 4,342 ( 2.2%) validation_mismatched_block_arity: 55 ( 0.0%) Top-2 unhandled HIR insns (100.0% of total 229,876): throw: 194,101 (84.4%) invokebuiltin: 35,775 (15.6%) Top-19 side exit reasons (100.0% of total 8,638,646): guard_type_failure: 7,693,566 (89.1%) unhandled_hir_insn: 229,876 ( 2.7%) compile_error: 196,386 ( 2.3%) patchpoint_method_redefined: 118,676 ( 1.4%) block_param_proxy_fallback_miss: 112,548 ( 1.3%) no_profile_send: 93,330 ( 1.1%) block_param_proxy_not_nil: 75,195 ( 0.9%) patchpoint_stable_constant_names: 55,792 ( 0.6%) patchpoint_no_singleton_class: 19,326 ( 0.2%) unhandled_block_arg: 14,540 ( 0.2%) block_param_proxy_not_iseq_or_ifunc: 13,401 ( 0.2%) fixnum_lshift_overflow: 10,165 ( 0.1%) guard_less_failure: 3,119 ( 0.0%) guard_shape_failure: 1,302 ( 0.0%) guard_greater_eq_failure: 941 ( 0.0%) guard_super_method_entry: 407 ( 0.0%) interrupt: 45 ( 0.0%) obj_to_string_fallback: 30 ( 0.0%) guard_not_shared_failure: 1 ( 0.0%) send_count: 182,477,537 dynamic_send_count: 22,409,237 (12.3%) optimized_send_count: 160,068,300 (87.7%) dynamic_setivar_count: 4,182,216 ( 2.3%) dynamic_getivar_count: 11,716,471 ( 6.4%) dynamic_definedivar_count: 503,058 ( 0.3%) iseq_optimized_send_count: 54,138,292 (29.7%) inline_cfunc_optimized_send_count: 74,815,196 (41.0%) inline_iseq_optimized_send_count: 6,346,484 ( 3.5%) non_variadic_cfunc_optimized_send_count: 13,788,597 ( 7.6%) variadic_cfunc_optimized_send_count: 10,979,731 ( 6.0%) compiled_iseq_count: 6,167 compiled_side_exit_count: 80,471 failed_iseq_count: 3 compile_time: 2,711ms compile_side_exit_time: 125ms compile_side_exit_time_ratio: 4.6% compile_hir_time: 870ms compile_hir_build_time: 266ms compile_hir_strength_reduce_time: 347ms compile_hir_canonicalize_time: 52ms compile_hir_fold_constants_time: 40ms compile_hir_clean_cfg_time: 27ms compile_hir_eliminate_dead_code_time: 32ms compile_lir_time: 1,680ms profile_time: 48ms gc_time: 32ms invalidation_time: 15ms vm_write_jit_frame_count: 137,425,789 vm_write_sp_count: 137,425,789 vm_write_locals_count: 131,264,963 vm_write_stack_count: 131,264,963 vm_write_to_parent_iseq_local_count: 688,457 guard_type_count: 146,412,455 guard_type_exit_ratio: 5.3% guard_shape_count: 36,937,934 guard_shape_exit_ratio: 0.0% load_field_count: 211,394,883 store_field_count: 15,778,119 side_exit_size: 13,563,624 code_region_bytes: 33,505,280 side_exit_size_ratio: 40.5% zjit_alloc_bytes: 22,870,223 total_mem_bytes: 56,375,503 side_exit_count: 8,638,646 total_insn_count: 995,144,390 vm_insn_count: 115,472,694 zjit_insn_count: 879,671,696 ratio_in_zjit: 88.4% ``` </details> * ZJIT: Add TODO for deduplicating DefinedIvar specialization * ZJIT: Add more DefinedIvar HIR tests Cover unsupported receiver profiles and a mixed polymorphic profile with a generic DefinedIvar fallback. * ZJIT: Add more DefinedIvar polymorphic HIR test Cover polymorphic definedivar profiles with: - complex path - non-T_OBJECT path
Diffstat (limited to 'sample/trick2025')
0 files changed, 0 insertions, 0 deletions