summaryrefslogtreecommitdiff
path: root/zjit/src
AgeCommit message (Collapse)Author
2025-10-27ZJIT: Use .is_empty() for clarityAiden Fox Ivey
2025-10-27ZJIT: Use .first() in lieu of .get(0)Aiden Fox Ivey
2025-10-27ZJIT: Elide unnecessary 'static annotationAiden Fox Ivey
2025-10-27ZJIT: Remove unnecessary `as` castsAiden Fox Ivey
2025-10-27ZJIT: Use std::ptr::null instead of castsAiden Fox Ivey
2025-10-27ZJIT: Remove unnecessary #[test] annotationAiden Fox Ivey
2025-10-27ZJIT: Simplify complex type to BranchEncoderAiden Fox Ivey
2025-10-27ZJIT: Elide unnecessary return statementsAiden Fox Ivey
2025-10-27ZJIT: Remove a duplicated annotation (#14968)Takashi Kokubun
2025-10-24ZJIT: Add gen_stack_overflow_check to `CCallWithFrame`Aiden Fox Ivey
2025-10-24ZJIT: Specialize string length, bytesize, and size (#14928)Jacob
Don't push frame for String#size, String#bytesize, and String#length.
2025-10-23ZJIT: s/as_usize/to_usize/ to comply with rust API guidelinesAlan Wu
When the name is `as_*`, the guideline expects the return type to be a reference type. Also, it's good to have contrast in the naming from the more dangerous `as usize` cast `IntoUsize` is meant to be preferred over. See: https://rust-lang.github.io/api-guidelines/naming.html
2025-10-23ZJIT: Replace `as usize` casts in codegen.rsAlan Wu
The `as` casts are somewhat dangerous since when the type on either side change, it silently becomes a lossy conversion. This is why we have `IntoUsize` as well as other guaranteed lossless conversion utilities in stdlib. Use them. For pointers-to-address, `ptr::addr` is more informative. See also: https://tratt.net/laurie/blog/2021/static_integer_types.html
2025-10-23ZJIT: Inline << and push for Array in single arg case (#14926)Aiden Fox Ivey
Fixes https://github.com/Shopify/ruby/issues/813
2025-10-23ZJIT: Use iseq pointer directly in get/set class var codegen (#14921)Stan Lo
Addresses https://github.com/ruby/ruby/pull/14918#discussion_r2453802886
2025-10-22ZJIT: Implement classvar get and set (#14918)Daniel Colson
https://github.com/Shopify/ruby/issues/649 Class vars are a bit more involved than ivars, since we need to get the class from the cref, so this calls out to `rb_vm_getclassvariable` and `rb_vm_setclassvariable` like YJIT.
2025-10-22ZJIT: Use InvokeBuiltin leaf attribute in codegenMax Bernstein
2025-10-22ZJIT: Fetch Primitive.attr!(leaf) for InvokeBuiltinMax Bernstein
Fix https://github.com/Shopify/ruby/issues/670
2025-10-22ZJIT: Fix unused warnings in `make zjit-test` [ci skip]Alan Wu
2025-10-22ZJIT: Inline Kernel#block_given? (#14914)Max Bernstein
Fix https://github.com/Shopify/ruby/issues/832
2025-10-22ZJIT: Buffer writes to the perf mapAlan Wu
2025-10-22ZJIT: Handle invalid Counter on --zjit-trace-exits=counter (#14911)Aiden Fox Ivey
2025-10-22ZJIT: Inline String#==, String#===Max Bernstein
2025-10-22ZJIT: Fix Type::from_class for subclasses of built-in typesMax Bernstein
2025-10-22ZJIT: Fix land raceMax Bernstein
2025-10-22ZJIT: Inline simple SendWithoutBlockDirect (#14888)Max Bernstein
Copy the YJIT simple inliner except for the kwargs bit. It works great!
2025-10-22ZJIT: Fix some dead code in the backend (#14897)Takashi Kokubun
2025-10-22ZJIT: A64: Fix Lea with large displacement and overlapping registerAlan Wu
Previously, when the output register and the base register are the same in `out = Lea(Mem(out, disp))`, we did out = disp out = out + out Which wasn't the desired `out = out + disp`. Fixes a SEGV with `--zjit-call-threshold=2` in `bootstraptest/test_yjit.rb`.
2025-10-22ZJIT: Specialize String#<< to StringAppend (#14861)Aiden Fox Ivey
Fixes https://github.com/Shopify/ruby/issues/805
2025-10-21ZJIT: Handle when SetIvar raises FrozenErrorAlan Wu
2025-10-22ZJIT: Inline Fixnum#^Benoit Daloze
* Handled in cruby_methods.rs because there is no basic operation for Fixnum#^.
2025-10-21ZJIT: Issue `SendWithoutBlockDirect` to `VM_METHOD_TYPE_BMETHOD`Alan Wu
This helps ZJIT optimize ~300,000 more sends in ruby-bench's lobsters Top-6 not optimized method types for send_without_block Before After iseq: 713,899 (48.0%) iseq: 725,668 (62.4%) optimized: 359,864 (24.2%) optimized: 359,940 (31.0%) bmethod: 339,040 (22.8%) alias: 73,541 ( 6.3%) alias: 73,392 ( 4.9%) null: 2,521 ( 0.2%) null: 2,521 ( 0.2%) bmethod: 979 ( 0.1%) cfunc: 4 ( 0.0%) cfunc: 4 ( 0.0%)
2025-10-21YJIT: ZJIT: Extract common bindings to jit.c and remove unnamed enums.Alan Wu
The type name bindgen picks for anonymous enums creates desync issues on the bindgen CI checks.
2025-10-21ZJIT: Fix binding to `INVALID_SHAPE_ID` under `-std=c99 -pedantic`Alan Wu
``` /src/jit.c:19:5: error: ISO C restricts enumerator values to range of 'int' (4294967295 is too large) [-Werror,-Wpedantic] 19 | RB_INVALID_SHAPE_ID = INVALID_SHAPE_ID, | ^ ~~~~~~~~~~~~~~~~ ```
2025-10-20ZJIT: Implement codegen for FixnumMod (#14857)Max Bernstein
This is mostly to see what happens to the loops-times benchmark.
2025-10-20ZJIT: Optimize send with block into CCallWithFrame (#14863)Stan Lo
Since `Send` has a block iseq, I updated `CCallWithFrame` to take an optional `blockiseq` as well, and then generate `CCallWithFrame` for `Send` when the condition is right. ## Stats `liquid-render` Benchmark | Metric | Before | After | Change | |----------------------|--------------------|--------------------|--------------------- | | send_no_profiles | 3,209,418 (34.1%) | 4,119 (0.1%) | -3,205,299 (-99.9%) | | dynamic_send_count | 9,410,758 (23.1%) | 6,459,678 (15.9%) | -2,951,080 (-31.4%) | | optimized_send_count | 31,269,388 (76.9%) | 34,220,474 (84.1%) | +2,951,086 (+9.4%) | `lobsters` Benchmark | Metric | Before | After | Change | |----------------------|------------|------------|---------------------| | send_no_profiles | 10,769,052 | 2,902,865 | -7,866,187 (-73.0%) | | dynamic_send_count | 45,673,185 | 42,880,160 | -2,793,025 (-6.1%) | | optimized_send_count | 75,142,407 | 78,378,514 | +3,236,107 (+4.3%) | ### `liquid-render` Before <details> ``` Average of last 22, non-warmup iters: 262ms ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (96.9% of total 10,370,809): Kernel#respond_to?: 5,069,204 (48.9%) Hash#key?: 2,394,488 (23.1%) Set#include?: 778,429 ( 7.5%) String#===: 326,134 ( 3.1%) String#<<: 203,231 ( 2.0%) Integer#<<: 166,768 ( 1.6%) Kernel#is_a?: 164,272 ( 1.6%) Kernel#format: 124,262 ( 1.2%) Integer#/: 124,262 ( 1.2%) Array#<<: 115,325 ( 1.1%) Regexp.last_match: 94,862 ( 0.9%) Hash#[]=: 88,485 ( 0.9%) String#start_with?: 55,933 ( 0.5%) CGI::EscapeExt#escapeHTML: 55,471 ( 0.5%) Array#shift: 55,298 ( 0.5%) Regexp#===: 48,928 ( 0.5%) String#=~: 48,477 ( 0.5%) Array#unshift: 47,331 ( 0.5%) String#empty?: 42,870 ( 0.4%) Array#push: 41,215 ( 0.4%) Top-20 not annotated C methods (97.1% of total 10,394,421): Kernel#respond_to?: 5,069,204 (48.8%) Hash#key?: 2,394,488 (23.0%) Set#include?: 778,429 ( 7.5%) String#===: 326,134 ( 3.1%) Kernel#is_a?: 208,664 ( 2.0%) String#<<: 203,231 ( 2.0%) Integer#<<: 166,768 ( 1.6%) Integer#/: 124,262 ( 1.2%) Kernel#format: 124,262 ( 1.2%) Array#<<: 115,325 ( 1.1%) Regexp.last_match: 94,862 ( 0.9%) Hash#[]=: 88,485 ( 0.9%) String#start_with?: 55,933 ( 0.5%) CGI::EscapeExt#escapeHTML: 55,471 ( 0.5%) Array#shift: 55,298 ( 0.5%) Regexp#===: 48,928 ( 0.5%) String#=~: 48,477 ( 0.5%) Array#unshift: 47,331 ( 0.5%) String#empty?: 42,870 ( 0.4%) Array#push: 41,215 ( 0.4%) Top-2 not optimized method types for send (100.0% of total 2,382): cfunc: 1,196 (50.2%) iseq: 1,186 (49.8%) Top-4 not optimized method types for send_without_block (100.0% of total 2,561,006): iseq: 2,442,091 (95.4%) optimized: 118,882 ( 4.6%) alias: 20 ( 0.0%) null: 13 ( 0.0%) Top-9 not optimized instructions (100.0% of total 685,128): invokeblock: 227,376 (33.2%) opt_neq: 166,471 (24.3%) opt_and: 166,471 (24.3%) opt_eq: 66,721 ( 9.7%) invokesuper: 39,363 ( 5.7%) opt_le: 16,278 ( 2.4%) opt_minus: 1,574 ( 0.2%) opt_send_without_block: 772 ( 0.1%) opt_or: 102 ( 0.0%) Top-8 send fallback reasons (100.0% of total 9,410,758): send_no_profiles: 3,209,418 (34.1%) send_without_block_polymorphic: 2,858,558 (30.4%) send_without_block_not_optimized_method_type: 2,561,006 (27.2%) not_optimized_instruction: 685,128 ( 7.3%) send_without_block_no_profiles: 91,913 ( 1.0%) send_not_optimized_method_type: 2,382 ( 0.0%) obj_to_string_not_string: 2,352 ( 0.0%) send_without_block_cfunc_array_variadic: 1 ( 0.0%) Top-3 unhandled YARV insns (100.0% of total 83,682): getclassvariable: 83,431 (99.7%) once: 137 ( 0.2%) getconstant: 114 ( 0.1%) Top-3 compile error reasons (100.0% of total 5,431,910): register_spill_on_alloc: 4,665,393 (85.9%) exception_handler: 766,347 (14.1%) register_spill_on_ccall: 170 ( 0.0%) Top-11 side exit reasons (100.0% of total 14,635,508): compile_error: 5,431,910 (37.1%) guard_shape_failure: 3,436,341 (23.5%) guard_type_failure: 2,545,791 (17.4%) unhandled_splat: 2,162,907 (14.8%) unhandled_kwarg: 952,568 ( 6.5%) unhandled_yarv_insn: 83,682 ( 0.6%) unhandled_hir_insn: 19,112 ( 0.1%) patchpoint_stable_constant_names: 1,608 ( 0.0%) obj_to_string_fallback: 902 ( 0.0%) patchpoint_method_redefined: 599 ( 0.0%) block_param_proxy_not_iseq_or_ifunc: 88 ( 0.0%) send_count: 40,680,153 dynamic_send_count: 9,410,758 (23.1%) optimized_send_count: 31,269,395 (76.9%) iseq_optimized_send_count: 13,886,902 (34.1%) inline_cfunc_optimized_send_count: 7,011,684 (17.2%) non_variadic_cfunc_optimized_send_count: 4,670,333 (11.5%) variadic_cfunc_optimized_send_count: 5,700,476 (14.0%) dynamic_getivar_count: 1,144,613 dynamic_setivar_count: 950,830 compiled_iseq_count: 402 failed_iseq_count: 48 compile_time: 976ms profile_time: 3,223ms gc_time: 22ms invalidation_time: 0ms vm_write_pc_count: 37,744,491 vm_write_sp_count: 37,511,865 vm_write_locals_count: 37,511,865 vm_write_stack_count: 37,511,865 vm_write_to_parent_iseq_local_count: 558,177 vm_read_from_parent_iseq_local_count: 14,317,032 code_region_bytes: 2,211,840 side_exit_count: 14,635,508 total_insn_count: 476,097,972 vm_insn_count: 253,795,154 zjit_insn_count: 222,302,818 ratio_in_zjit: 46.7% ``` </details> ### `liquid-render` After <details> ``` Average of last 21, non-warmup iters: 272ms ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (96.8% of total 10,093,966): Kernel#respond_to?: 4,932,224 (48.9%) Hash#key?: 2,329,928 (23.1%) Set#include?: 757,389 ( 7.5%) String#===: 317,494 ( 3.1%) String#<<: 197,831 ( 2.0%) Integer#<<: 162,268 ( 1.6%) Kernel#is_a?: 159,892 ( 1.6%) Kernel#format: 120,902 ( 1.2%) Integer#/: 120,902 ( 1.2%) Array#<<: 112,225 ( 1.1%) Regexp.last_match: 92,382 ( 0.9%) Hash#[]=: 86,145 ( 0.9%) String#start_with?: 54,953 ( 0.5%) Array#shift: 54,038 ( 0.5%) CGI::EscapeExt#escapeHTML: 53,971 ( 0.5%) Regexp#===: 47,848 ( 0.5%) String#=~: 47,237 ( 0.5%) Array#unshift: 46,051 ( 0.5%) String#empty?: 41,750 ( 0.4%) Array#push: 40,115 ( 0.4%) Top-20 not annotated C methods (97.1% of total 10,116,938): Kernel#respond_to?: 4,932,224 (48.8%) Hash#key?: 2,329,928 (23.0%) Set#include?: 757,389 ( 7.5%) String#===: 317,494 ( 3.1%) Kernel#is_a?: 203,084 ( 2.0%) String#<<: 197,831 ( 2.0%) Integer#<<: 162,268 ( 1.6%) Kernel#format: 120,902 ( 1.2%) Integer#/: 120,902 ( 1.2%) Array#<<: 112,225 ( 1.1%) Regexp.last_match: 92,382 ( 0.9%) Hash#[]=: 86,145 ( 0.9%) String#start_with?: 54,953 ( 0.5%) Array#shift: 54,038 ( 0.5%) CGI::EscapeExt#escapeHTML: 53,971 ( 0.5%) Regexp#===: 47,848 ( 0.5%) String#=~: 47,237 ( 0.5%) Array#unshift: 46,051 ( 0.5%) String#empty?: 41,750 ( 0.4%) Array#push: 40,115 ( 0.4%) Top-2 not optimized method types for send (100.0% of total 182,938): iseq: 178,414 (97.5%) cfunc: 4,524 ( 2.5%) Top-4 not optimized method types for send_without_block (100.0% of total 2,492,246): iseq: 2,376,511 (95.4%) optimized: 115,702 ( 4.6%) alias: 20 ( 0.0%) null: 13 ( 0.0%) Top-9 not optimized instructions (100.0% of total 667,727): invokeblock: 221,375 (33.2%) opt_neq: 161,971 (24.3%) opt_and: 161,971 (24.3%) opt_eq: 64,921 ( 9.7%) invokesuper: 39,243 ( 5.9%) opt_le: 15,838 ( 2.4%) opt_minus: 1,534 ( 0.2%) opt_send_without_block: 772 ( 0.1%) opt_or: 102 ( 0.0%) Top-9 send fallback reasons (100.0% of total 6,287,956): send_without_block_polymorphic: 2,782,058 (44.2%) send_without_block_not_optimized_method_type: 2,492,246 (39.6%) not_optimized_instruction: 667,727 (10.6%) send_not_optimized_method_type: 182,938 ( 2.9%) send_without_block_no_profiles: 89,613 ( 1.4%) send_polymorphic: 66,962 ( 1.1%) send_no_profiles: 4,059 ( 0.1%) obj_to_string_not_string: 2,352 ( 0.0%) send_without_block_cfunc_array_variadic: 1 ( 0.0%) Top-3 unhandled YARV insns (100.0% of total 81,482): getclassvariable: 81,231 (99.7%) once: 137 ( 0.2%) getconstant: 114 ( 0.1%) Top-3 compile error reasons (100.0% of total 5,286,310): register_spill_on_alloc: 4,540,413 (85.9%) exception_handler: 745,727 (14.1%) register_spill_on_ccall: 170 ( 0.0%) Top-12 side exit reasons (100.0% of total 14,244,881): compile_error: 5,286,310 (37.1%) guard_shape_failure: 3,346,873 (23.5%) guard_type_failure: 2,477,071 (17.4%) unhandled_splat: 2,104,447 (14.8%) unhandled_kwarg: 926,828 ( 6.5%) unhandled_yarv_insn: 81,482 ( 0.6%) unhandled_hir_insn: 18,672 ( 0.1%) patchpoint_stable_constant_names: 1,608 ( 0.0%) obj_to_string_fallback: 902 ( 0.0%) patchpoint_method_redefined: 599 ( 0.0%) block_param_proxy_not_iseq_or_ifunc: 88 ( 0.0%) interrupt: 1 ( 0.0%) send_count: 39,591,410 dynamic_send_count: 6,287,956 (15.9%) optimized_send_count: 33,303,454 (84.1%) iseq_optimized_send_count: 13,514,283 (34.1%) inline_cfunc_optimized_send_count: 6,823,745 (17.2%) non_variadic_cfunc_optimized_send_count: 7,417,432 (18.7%) variadic_cfunc_optimized_send_count: 5,547,994 (14.0%) dynamic_getivar_count: 1,110,647 dynamic_setivar_count: 927,309 compiled_iseq_count: 403 failed_iseq_count: 48 compile_time: 968ms profile_time: 3,547ms gc_time: 22ms invalidation_time: 0ms vm_write_pc_count: 36,735,108 vm_write_sp_count: 36,508,262 vm_write_locals_count: 36,508,262 vm_write_stack_count: 36,508,262 vm_write_to_parent_iseq_local_count: 543,097 vm_read_from_parent_iseq_local_count: 13,930,672 code_region_bytes: 2,228,224 side_exit_count: 14,244,881 total_insn_count: 463,357,969 vm_insn_count: 247,003,727 zjit_insn_count: 216,354,242 ratio_in_zjit: 46.7% ``` </details> ### `lobsters` Before <details> ``` Average of last 10, non-warmup iters: 898ms ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (61.3% of total 19,495,906): String#<<: 1,764,437 ( 9.1%) Kernel#is_a?: 1,615,120 ( 8.3%) Hash#[]=: 1,159,455 ( 5.9%) Regexp#match?: 777,496 ( 4.0%) String#empty?: 722,953 ( 3.7%) Hash#key?: 685,258 ( 3.5%) Kernel#respond_to?: 602,017 ( 3.1%) TrueClass#===: 447,671 ( 2.3%) FalseClass#===: 439,276 ( 2.3%) Array#include?: 426,758 ( 2.2%) Kernel#block_given?: 405,271 ( 2.1%) Hash#fetch: 382,302 ( 2.0%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) String#start_with?: 353,793 ( 1.8%) Kernel#kind_of?: 340,341 ( 1.7%) Kernel#dup: 328,162 ( 1.7%) String.new: 306,667 ( 1.6%) String#==: 287,549 ( 1.5%) BasicObject#!=: 284,642 ( 1.5%) String#length: 256,070 ( 1.3%) Top-20 not annotated C methods (62.4% of total 19,796,172): Kernel#is_a?: 1,993,676 (10.1%) String#<<: 1,764,437 ( 8.9%) Hash#[]=: 1,159,634 ( 5.9%) Regexp#match?: 777,496 ( 3.9%) String#empty?: 738,030 ( 3.7%) Hash#key?: 685,258 ( 3.5%) Kernel#respond_to?: 602,017 ( 3.0%) TrueClass#===: 447,671 ( 2.3%) FalseClass#===: 439,276 ( 2.2%) Array#include?: 426,758 ( 2.2%) Kernel#block_given?: 425,813 ( 2.2%) Hash#fetch: 382,302 ( 1.9%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) String#start_with?: 353,793 ( 1.8%) Kernel#kind_of?: 340,375 ( 1.7%) Kernel#dup: 328,169 ( 1.7%) String.new: 306,667 ( 1.5%) String#==: 293,520 ( 1.5%) BasicObject#!=: 284,825 ( 1.4%) String#length: 256,070 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 115,007): cfunc: 76,172 (66.2%) iseq: 38,835 (33.8%) Top-6 not optimized method types for send_without_block (100.0% of total 8,003,641): iseq: 3,999,211 (50.0%) bmethod: 1,750,271 (21.9%) optimized: 1,653,426 (20.7%) alias: 591,342 ( 7.4%) null: 8,174 ( 0.1%) cfunc: 1,217 ( 0.0%) Top-13 not optimized instructions (100.0% of total 7,590,826): invokesuper: 4,335,446 (57.1%) invokeblock: 1,329,215 (17.5%) sendforward: 841,463 (11.1%) opt_eq: 810,614 (10.7%) opt_plus: 141,773 ( 1.9%) opt_minus: 52,270 ( 0.7%) opt_send_without_block: 43,248 ( 0.6%) opt_neq: 15,047 ( 0.2%) opt_mult: 13,824 ( 0.2%) opt_or: 7,451 ( 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 45,673,212): send_without_block_polymorphic: 17,390,335 (38.1%) send_no_profiles: 10,769,053 (23.6%) send_without_block_not_optimized_method_type: 8,003,641 (17.5%) not_optimized_instruction: 7,590,826 (16.6%) send_without_block_no_profiles: 1,757,109 ( 3.8%) send_not_optimized_method_type: 115,007 ( 0.3%) send_without_block_cfunc_array_variadic: 31,149 ( 0.1%) obj_to_string_not_string: 15,518 ( 0.0%) send_without_block_direct_too_many_args: 574 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 1,242,228): expandarray: 622,203 (50.1%) checkkeyword: 316,111 (25.4%) getclassvariable: 120,540 ( 9.7%) getblockparam: 88,480 ( 7.1%) invokesuperforward: 78,842 ( 6.3%) opt_duparray_send: 14,149 ( 1.1%) getconstant: 1,588 ( 0.1%) checkmatch: 288 ( 0.0%) once: 27 ( 0.0%) Top-3 compile error reasons (100.0% of total 6,769,693): register_spill_on_alloc: 6,188,305 (91.4%) register_spill_on_ccall: 347,108 ( 5.1%) exception_handler: 234,280 ( 3.5%) Top-17 side exit reasons (100.0% of total 20,142,827): compile_error: 6,769,693 (33.6%) guard_type_failure: 5,169,050 (25.7%) guard_shape_failure: 3,726,362 (18.5%) unhandled_yarv_insn: 1,242,228 ( 6.2%) block_param_proxy_not_iseq_or_ifunc: 984,480 ( 4.9%) unhandled_kwarg: 800,154 ( 4.0%) unknown_newarray_send: 539,317 ( 2.7%) patchpoint_stable_constant_names: 340,283 ( 1.7%) unhandled_splat: 229,440 ( 1.1%) unhandled_hir_insn: 147,351 ( 0.7%) patchpoint_no_singleton_class: 128,856 ( 0.6%) patchpoint_method_redefined: 32,718 ( 0.2%) block_param_proxy_modified: 25,274 ( 0.1%) patchpoint_no_ep_escape: 7,559 ( 0.0%) obj_to_string_fallback: 24 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 16 ( 0.0%) send_count: 120,815,640 dynamic_send_count: 45,673,212 (37.8%) optimized_send_count: 75,142,428 (62.2%) iseq_optimized_send_count: 32,188,039 (26.6%) inline_cfunc_optimized_send_count: 23,458,483 (19.4%) non_variadic_cfunc_optimized_send_count: 14,809,797 (12.3%) variadic_cfunc_optimized_send_count: 4,686,109 ( 3.9%) dynamic_getivar_count: 13,023,437 dynamic_setivar_count: 12,311,158 compiled_iseq_count: 4,806 failed_iseq_count: 466 compile_time: 8,943ms profile_time: 99ms gc_time: 45ms invalidation_time: 239ms vm_write_pc_count: 113,652,291 vm_write_sp_count: 111,209,623 vm_write_locals_count: 111,209,623 vm_write_stack_count: 111,209,623 vm_write_to_parent_iseq_local_count: 516,800 vm_read_from_parent_iseq_local_count: 11,225,587 code_region_bytes: 22,609,920 side_exit_count: 20,142,827 total_insn_count: 926,088,942 vm_insn_count: 297,636,255 zjit_insn_count: 628,452,687 ratio_in_zjit: 67.9% ``` </details> ### `lobsters` After <details> ``` Average of last 10, non-warmup iters: 919ms ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (61.3% of total 19,495,868): String#<<: 1,764,437 ( 9.1%) Kernel#is_a?: 1,615,110 ( 8.3%) Hash#[]=: 1,159,455 ( 5.9%) Regexp#match?: 777,496 ( 4.0%) String#empty?: 722,953 ( 3.7%) Hash#key?: 685,258 ( 3.5%) Kernel#respond_to?: 602,016 ( 3.1%) TrueClass#===: 447,671 ( 2.3%) FalseClass#===: 439,276 ( 2.3%) Array#include?: 426,758 ( 2.2%) Kernel#block_given?: 405,271 ( 2.1%) Hash#fetch: 382,302 ( 2.0%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) String#start_with?: 353,793 ( 1.8%) Kernel#kind_of?: 340,341 ( 1.7%) Kernel#dup: 328,162 ( 1.7%) String.new: 306,667 ( 1.6%) String#==: 287,545 ( 1.5%) BasicObject#!=: 284,642 ( 1.5%) String#length: 256,070 ( 1.3%) Top-20 not annotated C methods (62.4% of total 19,796,134): Kernel#is_a?: 1,993,666 (10.1%) String#<<: 1,764,437 ( 8.9%) Hash#[]=: 1,159,634 ( 5.9%) Regexp#match?: 777,496 ( 3.9%) String#empty?: 738,030 ( 3.7%) Hash#key?: 685,258 ( 3.5%) Kernel#respond_to?: 602,016 ( 3.0%) TrueClass#===: 447,671 ( 2.3%) FalseClass#===: 439,276 ( 2.2%) Array#include?: 426,758 ( 2.2%) Kernel#block_given?: 425,813 ( 2.2%) Hash#fetch: 382,302 ( 1.9%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) String#start_with?: 353,793 ( 1.8%) Kernel#kind_of?: 340,375 ( 1.7%) Kernel#dup: 328,169 ( 1.7%) String.new: 306,667 ( 1.5%) String#==: 293,516 ( 1.5%) BasicObject#!=: 284,825 ( 1.4%) String#length: 256,070 ( 1.3%) Top-4 not optimized method types for send (100.0% of total 4,749,678): iseq: 2,563,391 (54.0%) cfunc: 2,064,888 (43.5%) alias: 118,577 ( 2.5%) null: 2,822 ( 0.1%) Top-6 not optimized method types for send_without_block (100.0% of total 8,003,641): iseq: 3,999,211 (50.0%) bmethod: 1,750,271 (21.9%) optimized: 1,653,426 (20.7%) alias: 591,342 ( 7.4%) null: 8,174 ( 0.1%) cfunc: 1,217 ( 0.0%) Top-13 not optimized instructions (100.0% of total 7,590,818): invokesuper: 4,335,442 (57.1%) invokeblock: 1,329,215 (17.5%) sendforward: 841,463 (11.1%) opt_eq: 810,610 (10.7%) opt_plus: 141,773 ( 1.9%) opt_minus: 52,270 ( 0.7%) opt_send_without_block: 43,248 ( 0.6%) opt_neq: 15,047 ( 0.2%) opt_mult: 13,824 ( 0.2%) opt_or: 7,451 ( 0.1%) opt_lt: 348 ( 0.0%) opt_ge: 91 ( 0.0%) opt_gt: 36 ( 0.0%) Top-10 send fallback reasons (100.0% of total 43,152,037): send_without_block_polymorphic: 17,390,322 (40.3%) send_without_block_not_optimized_method_type: 8,003,641 (18.5%) not_optimized_instruction: 7,590,818 (17.6%) send_not_optimized_method_type: 4,749,678 (11.0%) send_no_profiles: 2,893,666 ( 6.7%) send_without_block_no_profiles: 1,757,109 ( 4.1%) send_polymorphic: 719,562 ( 1.7%) send_without_block_cfunc_array_variadic: 31,149 ( 0.1%) obj_to_string_not_string: 15,518 ( 0.0%) send_without_block_direct_too_many_args: 574 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 1,242,215): expandarray: 622,203 (50.1%) checkkeyword: 316,111 (25.4%) getclassvariable: 120,540 ( 9.7%) getblockparam: 88,467 ( 7.1%) invokesuperforward: 78,842 ( 6.3%) opt_duparray_send: 14,149 ( 1.1%) getconstant: 1,588 ( 0.1%) checkmatch: 288 ( 0.0%) once: 27 ( 0.0%) Top-3 compile error reasons (100.0% of total 6,769,688): register_spill_on_alloc: 6,188,305 (91.4%) register_spill_on_ccall: 347,108 ( 5.1%) exception_handler: 234,275 ( 3.5%) Top-17 side exit reasons (100.0% of total 20,144,372): compile_error: 6,769,688 (33.6%) guard_type_failure: 5,169,204 (25.7%) guard_shape_failure: 3,726,374 (18.5%) unhandled_yarv_insn: 1,242,215 ( 6.2%) block_param_proxy_not_iseq_or_ifunc: 984,480 ( 4.9%) unhandled_kwarg: 800,154 ( 4.0%) unknown_newarray_send: 539,317 ( 2.7%) patchpoint_stable_constant_names: 340,283 ( 1.7%) unhandled_splat: 229,440 ( 1.1%) unhandled_hir_insn: 147,351 ( 0.7%) patchpoint_no_singleton_class: 130,252 ( 0.6%) patchpoint_method_redefined: 32,716 ( 0.2%) block_param_proxy_modified: 25,274 ( 0.1%) patchpoint_no_ep_escape: 7,559 ( 0.0%) obj_to_string_fallback: 24 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 19 ( 0.0%) send_count: 120,812,030 dynamic_send_count: 43,152,037 (35.7%) optimized_send_count: 77,659,993 (64.3%) iseq_optimized_send_count: 32,187,900 (26.6%) inline_cfunc_optimized_send_count: 23,458,491 (19.4%) non_variadic_cfunc_optimized_send_count: 17,327,499 (14.3%) variadic_cfunc_optimized_send_count: 4,686,103 ( 3.9%) dynamic_getivar_count: 13,023,424 dynamic_setivar_count: 12,310,991 compiled_iseq_count: 4,806 failed_iseq_count: 466 compile_time: 9,012ms profile_time: 104ms gc_time: 44ms invalidation_time: 239ms vm_write_pc_count: 113,648,665 vm_write_sp_count: 111,205,997 vm_write_locals_count: 111,205,997 vm_write_stack_count: 111,205,997 vm_write_to_parent_iseq_local_count: 516,800 vm_read_from_parent_iseq_local_count: 11,225,587 code_region_bytes: 23,052,288 side_exit_count: 20,144,372 total_insn_count: 926,090,214 vm_insn_count: 297,647,811 zjit_insn_count: 628,442,403 ratio_in_zjit: 67.9% ``` </details>
2025-10-20ZJIT: Remove idx from hir::Insn::Param (#14872)Max Bernstein
It turns out that we don't use it anywhere.
2025-10-20ZJIT: Implement expandarray (#14847)Max Bernstein
Only support the simple case: no splat or rest. lobsters before: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (60.5% of total 11,039,954): Kernel#is_a?: 1,030,769 ( 9.3%) String#<<: 851,954 ( 7.7%) Hash#[]=: 742,941 ( 6.7%) Regexp#match?: 399,894 ( 3.6%) String#empty?: 353,775 ( 3.2%) Hash#key?: 349,147 ( 3.2%) String#start_with?: 334,961 ( 3.0%) Kernel#respond_to?: 316,528 ( 2.9%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.2%) TrueClass#===: 235,771 ( 2.1%) FalseClass#===: 231,144 ( 2.1%) Array#include?: 211,385 ( 1.9%) Hash#fetch: 204,702 ( 1.9%) Kernel#block_given?: 181,797 ( 1.6%) Kernel#dup: 179,341 ( 1.6%) BasicObject#!=: 175,997 ( 1.6%) Class#new: 168,079 ( 1.5%) Kernel#kind_of?: 165,600 ( 1.5%) String#==: 157,735 ( 1.4%) Module#clock_gettime: 144,992 ( 1.3%) Top-20 not annotated C methods (61.4% of total 11,202,087): Kernel#is_a?: 1,212,660 (10.8%) String#<<: 851,954 ( 7.6%) Hash#[]=: 743,120 ( 6.6%) Regexp#match?: 399,894 ( 3.6%) String#empty?: 361,013 ( 3.2%) Hash#key?: 349,147 ( 3.1%) String#start_with?: 334,961 ( 3.0%) Kernel#respond_to?: 316,528 ( 2.8%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.1%) TrueClass#===: 235,771 ( 2.1%) FalseClass#===: 231,144 ( 2.1%) Array#include?: 211,385 ( 1.9%) Hash#fetch: 204,702 ( 1.8%) Kernel#block_given?: 191,666 ( 1.7%) Kernel#dup: 179,348 ( 1.6%) BasicObject#!=: 176,181 ( 1.6%) Class#new: 168,079 ( 1.5%) Kernel#kind_of?: 165,634 ( 1.5%) String#==: 163,667 ( 1.5%) Module#clock_gettime: 144,992 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 72,318): cfunc: 48,055 (66.4%) iseq: 24,263 (33.6%) Top-6 not optimized method types for send_without_block (100.0% of total 4,523,682): iseq: 2,271,936 (50.2%) bmethod: 985,636 (21.8%) optimized: 949,703 (21.0%) alias: 310,747 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,293,171): invokesuper: 2,373,404 (55.3%) invokeblock: 811,926 (18.9%) sendforward: 505,452 (11.8%) opt_eq: 451,754 (10.5%) opt_plus: 74,404 ( 1.7%) opt_minus: 36,228 ( 0.8%) opt_send_without_block: 21,792 ( 0.5%) opt_neq: 7,231 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,753 ( 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,530,724): send_without_block_polymorphic: 9,722,491 (38.1%) send_no_profiles: 5,894,788 (23.1%) send_without_block_not_optimized_method_type: 4,523,682 (17.7%) not_optimized_instruction: 4,293,171 (16.8%) send_without_block_no_profiles: 998,746 ( 3.9%) send_not_optimized_method_type: 72,318 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,765 ( 0.0%) send_without_block_direct_too_many_args: 629 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 690,950): expandarray: 328,490 (47.5%) checkkeyword: 190,694 (27.6%) getclassvariable: 59,901 ( 8.7%) invokesuperforward: 49,503 ( 7.2%) getblockparam: 49,119 ( 7.1%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 952 ( 0.1%) checkmatch: 290 ( 0.0%) once: 23 ( 0.0%) Top-3 compile error reasons (100.0% of total 3,718,636): register_spill_on_alloc: 3,418,255 (91.9%) register_spill_on_ccall: 182,018 ( 4.9%) exception_handler: 118,363 ( 3.2%) Top-14 side exit reasons (100.0% of total 10,860,385): compile_error: 3,718,636 (34.2%) guard_type_failure: 2,638,926 (24.3%) guard_shape_failure: 1,917,209 (17.7%) unhandled_yarv_insn: 690,950 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 535,789 ( 4.9%) unhandled_kwarg: 455,347 ( 4.2%) patchpoint: 370,476 ( 3.4%) unknown_newarray_send: 314,786 ( 2.9%) unhandled_splat: 122,071 ( 1.1%) unhandled_hir_insn: 76,397 ( 0.7%) block_param_proxy_modified: 19,193 ( 0.2%) obj_to_string_fallback: 566 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 17 ( 0.0%) send_count: 62,244,604 dynamic_send_count: 25,530,724 (41.0%) optimized_send_count: 36,713,880 (59.0%) iseq_optimized_send_count: 18,587,512 (29.9%) inline_cfunc_optimized_send_count: 7,086,414 (11.4%) non_variadic_cfunc_optimized_send_count: 8,375,754 (13.5%) variadic_cfunc_optimized_send_count: 2,664,200 ( 4.3%) dynamic_getivar_count: 7,365,995 dynamic_setivar_count: 7,245,005 compiled_iseq_count: 4,796 failed_iseq_count: 447 compile_time: 814ms profile_time: 9ms gc_time: 9ms invalidation_time: 72ms vm_write_pc_count: 64,156,223 vm_write_sp_count: 62,812,449 vm_write_locals_count: 62,812,449 vm_write_stack_count: 62,812,449 vm_write_to_parent_iseq_local_count: 292,458 vm_read_from_parent_iseq_local_count: 6,599,701 code_region_bytes: 22,953,984 side_exit_count: 10,860,385 total_insn_count: 517,606,340 vm_insn_count: 162,979,530 zjit_insn_count: 354,626,810 ratio_in_zjit: 68.5% ``` </details> lobsters after: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (59.9% of total 11,291,815): Kernel#is_a?: 1,046,269 ( 9.3%) String#<<: 851,954 ( 7.5%) Hash#[]=: 743,274 ( 6.6%) Regexp#match?: 399,894 ( 3.5%) String#empty?: 353,775 ( 3.1%) Hash#key?: 349,147 ( 3.1%) String#start_with?: 334,961 ( 3.0%) Kernel#respond_to?: 316,502 ( 2.8%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.1%) TrueClass#===: 235,771 ( 2.1%) FalseClass#===: 231,144 ( 2.0%) String#sub!: 219,579 ( 1.9%) Array#include?: 211,385 ( 1.9%) Hash#fetch: 204,702 ( 1.8%) Kernel#block_given?: 181,797 ( 1.6%) Kernel#dup: 179,341 ( 1.6%) BasicObject#!=: 175,997 ( 1.6%) Class#new: 168,079 ( 1.5%) Kernel#kind_of?: 165,600 ( 1.5%) String#==: 157,742 ( 1.4%) Top-20 not annotated C methods (60.9% of total 11,466,928): Kernel#is_a?: 1,239,923 (10.8%) String#<<: 851,954 ( 7.4%) Hash#[]=: 743,453 ( 6.5%) Regexp#match?: 399,894 ( 3.5%) String#empty?: 361,013 ( 3.1%) Hash#key?: 349,147 ( 3.0%) String#start_with?: 334,961 ( 2.9%) Kernel#respond_to?: 316,502 ( 2.8%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.1%) TrueClass#===: 235,771 ( 2.1%) FalseClass#===: 231,144 ( 2.0%) String#sub!: 219,579 ( 1.9%) Array#include?: 211,385 ( 1.8%) Hash#fetch: 204,702 ( 1.8%) Kernel#block_given?: 191,666 ( 1.7%) Kernel#dup: 179,348 ( 1.6%) BasicObject#!=: 176,181 ( 1.5%) Class#new: 168,079 ( 1.5%) Kernel#kind_of?: 165,634 ( 1.4%) String#==: 163,674 ( 1.4%) Top-2 not optimized method types for send (100.0% of total 72,318): cfunc: 48,055 (66.4%) iseq: 24,263 (33.6%) Top-6 not optimized method types for send_without_block (100.0% of total 4,524,016): iseq: 2,272,269 (50.2%) bmethod: 985,636 (21.8%) optimized: 949,704 (21.0%) alias: 310,747 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,294,241): invokesuper: 2,375,446 (55.3%) invokeblock: 810,955 (18.9%) sendforward: 505,451 (11.8%) opt_eq: 451,754 (10.5%) opt_plus: 74,404 ( 1.7%) opt_minus: 36,228 ( 0.8%) opt_send_without_block: 21,792 ( 0.5%) opt_neq: 7,231 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,753 ( 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,534,542): send_without_block_polymorphic: 9,723,469 (38.1%) send_no_profiles: 5,896,023 (23.1%) send_without_block_not_optimized_method_type: 4,524,016 (17.7%) not_optimized_instruction: 4,294,241 (16.8%) send_without_block_no_profiles: 998,947 ( 3.9%) send_not_optimized_method_type: 72,318 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,765 ( 0.0%) send_without_block_direct_too_many_args: 629 ( 0.0%) Top-8 unhandled YARV insns (100.0% of total 362,460): checkkeyword: 190,694 (52.6%) getclassvariable: 59,901 (16.5%) invokesuperforward: 49,503 (13.7%) getblockparam: 49,119 (13.6%) opt_duparray_send: 11,978 ( 3.3%) getconstant: 952 ( 0.3%) checkmatch: 290 ( 0.1%) once: 23 ( 0.0%) Top-3 compile error reasons (100.0% of total 3,798,744): register_spill_on_alloc: 3,495,669 (92.0%) register_spill_on_ccall: 184,712 ( 4.9%) exception_handler: 118,363 ( 3.1%) Top-15 side exit reasons (100.0% of total 10,637,319): compile_error: 3,798,744 (35.7%) guard_type_failure: 2,655,504 (25.0%) guard_shape_failure: 1,917,217 (18.0%) block_param_proxy_not_iseq_or_ifunc: 535,789 ( 5.0%) unhandled_kwarg: 455,492 ( 4.3%) patchpoint: 370,478 ( 3.5%) unhandled_yarv_insn: 362,460 ( 3.4%) unknown_newarray_send: 314,786 ( 3.0%) unhandled_splat: 122,071 ( 1.1%) unhandled_hir_insn: 83,066 ( 0.8%) block_param_proxy_modified: 19,193 ( 0.2%) guard_int_equals_failure: 1,914 ( 0.0%) obj_to_string_fallback: 566 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 17 ( 0.0%) send_count: 62,495,067 dynamic_send_count: 25,534,542 (40.9%) optimized_send_count: 36,960,525 (59.1%) iseq_optimized_send_count: 18,582,072 (29.7%) inline_cfunc_optimized_send_count: 7,086,638 (11.3%) non_variadic_cfunc_optimized_send_count: 8,392,657 (13.4%) variadic_cfunc_optimized_send_count: 2,899,158 ( 4.6%) dynamic_getivar_count: 7,365,994 dynamic_setivar_count: 7,248,500 compiled_iseq_count: 4,780 failed_iseq_count: 463 compile_time: 816ms profile_time: 9ms gc_time: 11ms invalidation_time: 70ms vm_write_pc_count: 64,363,541 vm_write_sp_count: 63,022,221 vm_write_locals_count: 63,022,221 vm_write_stack_count: 63,022,221 vm_write_to_parent_iseq_local_count: 292,458 vm_read_from_parent_iseq_local_count: 6,850,977 code_region_bytes: 23,019,520 side_exit_count: 10,637,319 total_insn_count: 517,303,190 vm_insn_count: 160,562,103 zjit_insn_count: 356,741,087 ratio_in_zjit: 69.0% ``` </details> railsbench before: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (66.1% of total 25,524,934): Hash#[]=: 1,700,237 ( 6.7%) String#getbyte: 1,572,123 ( 6.2%) String#<<: 1,494,022 ( 5.9%) Kernel#is_a?: 1,429,930 ( 5.6%) String#empty?: 1,370,323 ( 5.4%) Regexp#match?: 1,235,067 ( 4.8%) Kernel#respond_to?: 1,198,251 ( 4.7%) Hash#key?: 1,087,406 ( 4.3%) String#setbyte: 810,022 ( 3.2%) Integer#^: 766,624 ( 3.0%) Kernel#block_given?: 603,613 ( 2.4%) String#==: 590,409 ( 2.3%) Class#new: 506,216 ( 2.0%) Hash#delete: 455,288 ( 1.8%) BasicObject#!=: 428,771 ( 1.7%) Hash#fetch: 408,621 ( 1.6%) String#ascii_only?: 373,915 ( 1.5%) ObjectSpace::WeakKeyMap#[]: 287,957 ( 1.1%) NilClass#===: 277,244 ( 1.1%) Kernel#Array: 269,590 ( 1.1%) Top-20 not annotated C methods (66.8% of total 25,392,654): Hash#[]=: 1,700,416 ( 6.7%) String#getbyte: 1,572,123 ( 6.2%) Kernel#is_a?: 1,515,672 ( 6.0%) String#<<: 1,494,022 ( 5.9%) String#empty?: 1,370,478 ( 5.4%) Regexp#match?: 1,235,067 ( 4.9%) Kernel#respond_to?: 1,198,251 ( 4.7%) Hash#key?: 1,087,406 ( 4.3%) String#setbyte: 810,022 ( 3.2%) Integer#^: 766,624 ( 3.0%) Kernel#block_given?: 603,613 ( 2.4%) String#==: 601,115 ( 2.4%) Class#new: 506,216 ( 2.0%) Hash#delete: 455,288 ( 1.8%) BasicObject#!=: 428,876 ( 1.7%) Hash#fetch: 408,621 ( 1.6%) String#ascii_only?: 373,915 ( 1.5%) ObjectSpace::WeakKeyMap#[]: 287,957 ( 1.1%) NilClass#===: 277,244 ( 1.1%) Kernel#Array: 269,590 ( 1.1%) Top-2 not optimized method types for send (100.0% of total 186,159): iseq: 112,747 (60.6%) cfunc: 73,412 (39.4%) Top-6 not optimized method types for send_without_block (100.0% of total 8,142,248): iseq: 3,464,671 (42.6%) optimized: 2,632,884 (32.3%) bmethod: 1,290,701 (15.9%) alias: 706,020 ( 8.7%) null: 47,942 ( 0.6%) cfunc: 30 ( 0.0%) Top-11 not optimized instructions (100.0% of total 8,394,873): invokesuper: 5,602,274 (66.7%) invokeblock: 1,764,936 (21.0%) sendforward: 551,832 ( 6.6%) opt_eq: 441,959 ( 5.3%) opt_plus: 31,635 ( 0.4%) opt_send_without_block: 1,163 ( 0.0%) opt_lt: 372 ( 0.0%) opt_mult: 251 ( 0.0%) opt_ge: 193 ( 0.0%) opt_neq: 149 ( 0.0%) opt_or: 109 ( 0.0%) Top-8 send fallback reasons (100.0% of total 40,748,753): send_without_block_polymorphic: 12,933,923 (31.7%) send_no_profiles: 9,033,636 (22.2%) not_optimized_instruction: 8,394,873 (20.6%) send_without_block_not_optimized_method_type: 8,142,248 (20.0%) send_without_block_no_profiles: 1,839,228 ( 4.5%) send_without_block_cfunc_array_variadic: 215,046 ( 0.5%) send_not_optimized_method_type: 186,159 ( 0.5%) obj_to_string_not_string: 3,640 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 1,604,456): getclassvariable: 458,136 (28.6%) getblockparam: 455,921 (28.4%) checkkeyword: 265,425 (16.5%) invokesuperforward: 239,383 (14.9%) expandarray: 137,305 ( 8.6%) getconstant: 48,100 ( 3.0%) checkmatch: 149 ( 0.0%) once: 23 ( 0.0%) opt_duparray_send: 14 ( 0.0%) Top-3 compile error reasons (100.0% of total 5,570,130): register_spill_on_alloc: 4,994,130 (89.7%) exception_handler: 356,784 ( 6.4%) register_spill_on_ccall: 219,216 ( 3.9%) Top-13 side exit reasons (100.0% of total 12,412,181): compile_error: 5,570,130 (44.9%) unhandled_yarv_insn: 1,604,456 (12.9%) guard_shape_failure: 1,462,872 (11.8%) guard_type_failure: 845,891 ( 6.8%) block_param_proxy_not_iseq_or_ifunc: 765,968 ( 6.2%) unhandled_kwarg: 658,341 ( 5.3%) patchpoint: 504,437 ( 4.1%) unhandled_splat: 446,990 ( 3.6%) unknown_newarray_send: 332,740 ( 2.7%) unhandled_hir_insn: 160,205 ( 1.3%) block_param_proxy_modified: 59,589 ( 0.5%) obj_to_string_fallback: 553 ( 0.0%) interrupt: 9 ( 0.0%) send_count: 119,067,587 dynamic_send_count: 40,748,753 (34.2%) optimized_send_count: 78,318,834 (65.8%) iseq_optimized_send_count: 39,936,542 (33.5%) inline_cfunc_optimized_send_count: 12,857,358 (10.8%) non_variadic_cfunc_optimized_send_count: 19,722,584 (16.6%) variadic_cfunc_optimized_send_count: 5,802,350 ( 4.9%) dynamic_getivar_count: 10,980,323 dynamic_setivar_count: 12,962,726 compiled_iseq_count: 2,531 failed_iseq_count: 245 compile_time: 414ms profile_time: 21ms gc_time: 33ms invalidation_time: 5ms vm_write_pc_count: 129,093,714 vm_write_sp_count: 126,023,084 vm_write_locals_count: 126,023,084 vm_write_stack_count: 126,023,084 vm_write_to_parent_iseq_local_count: 385,461 vm_read_from_parent_iseq_local_count: 11,266,484 code_region_bytes: 12,156,928 side_exit_count: 12,412,181 total_insn_count: 866,780,158 vm_insn_count: 216,821,134 zjit_insn_count: 649,959,024 ratio_in_zjit: 75.0% ``` </details> railsbench after: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (66.0% of total 25,597,895): Hash#[]=: 1,724,042 ( 6.7%) String#getbyte: 1,572,123 ( 6.1%) String#<<: 1,494,022 ( 5.8%) Kernel#is_a?: 1,429,946 ( 5.6%) String#empty?: 1,370,323 ( 5.4%) Regexp#match?: 1,235,067 ( 4.8%) Kernel#respond_to?: 1,198,251 ( 4.7%) Hash#key?: 1,087,406 ( 4.2%) String#setbyte: 810,022 ( 3.2%) Integer#^: 766,624 ( 3.0%) Kernel#block_given?: 603,613 ( 2.4%) String#==: 590,699 ( 2.3%) Class#new: 506,216 ( 2.0%) Hash#delete: 455,288 ( 1.8%) BasicObject#!=: 428,771 ( 1.7%) Hash#fetch: 408,621 ( 1.6%) String#ascii_only?: 373,915 ( 1.5%) ObjectSpace::WeakKeyMap#[]: 287,957 ( 1.1%) NilClass#===: 277,244 ( 1.1%) Kernel#Array: 269,590 ( 1.1%) Top-20 not annotated C methods (66.7% of total 25,465,615): Hash#[]=: 1,724,221 ( 6.8%) String#getbyte: 1,572,123 ( 6.2%) Kernel#is_a?: 1,515,688 ( 6.0%) String#<<: 1,494,022 ( 5.9%) String#empty?: 1,370,478 ( 5.4%) Regexp#match?: 1,235,067 ( 4.8%) Kernel#respond_to?: 1,198,251 ( 4.7%) Hash#key?: 1,087,406 ( 4.3%) String#setbyte: 810,022 ( 3.2%) Integer#^: 766,624 ( 3.0%) Kernel#block_given?: 603,613 ( 2.4%) String#==: 601,405 ( 2.4%) Class#new: 506,216 ( 2.0%) Hash#delete: 455,288 ( 1.8%) BasicObject#!=: 428,876 ( 1.7%) Hash#fetch: 408,621 ( 1.6%) String#ascii_only?: 373,915 ( 1.5%) ObjectSpace::WeakKeyMap#[]: 287,957 ( 1.1%) NilClass#===: 277,244 ( 1.1%) Kernel#Array: 269,590 ( 1.1%) Top-2 not optimized method types for send (100.0% of total 186,159): iseq: 112,747 (60.6%) cfunc: 73,412 (39.4%) Top-6 not optimized method types for send_without_block (100.0% of total 8,142,248): iseq: 3,464,671 (42.6%) optimized: 2,632,884 (32.3%) bmethod: 1,290,701 (15.9%) alias: 706,020 ( 8.7%) null: 47,942 ( 0.6%) cfunc: 30 ( 0.0%) Top-11 not optimized instructions (100.0% of total 8,442,456): invokesuper: 5,649,857 (66.9%) invokeblock: 1,764,936 (20.9%) sendforward: 551,832 ( 6.5%) opt_eq: 441,959 ( 5.2%) opt_plus: 31,635 ( 0.4%) opt_send_without_block: 1,163 ( 0.0%) opt_lt: 372 ( 0.0%) opt_mult: 251 ( 0.0%) opt_ge: 193 ( 0.0%) opt_neq: 149 ( 0.0%) opt_or: 109 ( 0.0%) Top-8 send fallback reasons (100.0% of total 40,796,314): send_without_block_polymorphic: 12,933,921 (31.7%) send_no_profiles: 9,033,616 (22.1%) not_optimized_instruction: 8,442,456 (20.7%) send_without_block_not_optimized_method_type: 8,142,248 (20.0%) send_without_block_no_profiles: 1,839,228 ( 4.5%) send_without_block_cfunc_array_variadic: 215,046 ( 0.5%) send_not_optimized_method_type: 186,159 ( 0.5%) obj_to_string_not_string: 3,640 ( 0.0%) Top-8 unhandled YARV insns (100.0% of total 1,467,151): getclassvariable: 458,136 (31.2%) getblockparam: 455,921 (31.1%) checkkeyword: 265,425 (18.1%) invokesuperforward: 239,383 (16.3%) getconstant: 48,100 ( 3.3%) checkmatch: 149 ( 0.0%) once: 23 ( 0.0%) opt_duparray_send: 14 ( 0.0%) Top-3 compile error reasons (100.0% of total 5,825,923): register_spill_on_alloc: 5,225,940 (89.7%) exception_handler: 356,784 ( 6.1%) register_spill_on_ccall: 243,199 ( 4.2%) Top-13 side exit reasons (100.0% of total 12,530,763): compile_error: 5,825,923 (46.5%) unhandled_yarv_insn: 1,467,151 (11.7%) guard_shape_failure: 1,462,876 (11.7%) guard_type_failure: 845,913 ( 6.8%) block_param_proxy_not_iseq_or_ifunc: 765,968 ( 6.1%) unhandled_kwarg: 658,341 ( 5.3%) patchpoint: 504,437 ( 4.0%) unhandled_splat: 446,990 ( 3.6%) unknown_newarray_send: 332,740 ( 2.7%) unhandled_hir_insn: 160,273 ( 1.3%) block_param_proxy_modified: 59,589 ( 0.5%) obj_to_string_fallback: 553 ( 0.0%) interrupt: 9 ( 0.0%) send_count: 119,163,569 dynamic_send_count: 40,796,314 (34.2%) optimized_send_count: 78,367,255 (65.8%) iseq_optimized_send_count: 39,911,967 (33.5%) inline_cfunc_optimized_send_count: 12,857,393 (10.8%) non_variadic_cfunc_optimized_send_count: 19,770,401 (16.6%) variadic_cfunc_optimized_send_count: 5,827,494 ( 4.9%) dynamic_getivar_count: 10,980,323 dynamic_setivar_count: 12,986,381 compiled_iseq_count: 2,523 failed_iseq_count: 252 compile_time: 420ms profile_time: 21ms gc_time: 30ms invalidation_time: 4ms vm_write_pc_count: 128,973,665 vm_write_sp_count: 125,926,968 vm_write_locals_count: 125,926,968 vm_write_stack_count: 125,926,968 vm_write_to_parent_iseq_local_count: 385,752 vm_read_from_parent_iseq_local_count: 11,267,766 code_region_bytes: 12,189,696 side_exit_count: 12,530,763 total_insn_count: 866,667,490 vm_insn_count: 217,813,201 zjit_insn_count: 648,854,289 ratio_in_zjit: 74.9% ``` </details>
2025-10-17ZJIT: Add inlining for Kernel#respond_to? (#14873)Aiden Fox Ivey
lobsters before: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (61.1% of total 10,568,718): Kernel#is_a?: 1,030,925 ( 9.8%) String#<<: 851,954 ( 8.1%) Hash#[]=: 742,942 ( 7.0%) Regexp#match?: 399,898 ( 3.8%) Hash#key?: 349,146 ( 3.3%) String#start_with?: 334,963 ( 3.2%) Kernel#respond_to?: 316,528 ( 3.0%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.3%) TrueClass#===: 235,771 ( 2.2%) FalseClass#===: 231,144 ( 2.2%) Array#include?: 211,386 ( 2.0%) Hash#fetch: 204,702 ( 1.9%) Kernel#block_given?: 181,796 ( 1.7%) Kernel#dup: 179,341 ( 1.7%) BasicObject#!=: 175,997 ( 1.7%) String.new: 166,696 ( 1.6%) Kernel#kind_of?: 165,600 ( 1.6%) String#==: 157,746 ( 1.5%) Process.clock_gettime: 144,992 ( 1.4%) Array#any?: 138,310 ( 1.3%) Top-20 not annotated C methods (62.1% of total 10,723,613): Kernel#is_a?: 1,212,816 (11.3%) String#<<: 851,954 ( 7.9%) Hash#[]=: 743,121 ( 6.9%) Regexp#match?: 399,898 ( 3.7%) Hash#key?: 349,146 ( 3.3%) String#start_with?: 334,963 ( 3.1%) Kernel#respond_to?: 316,528 ( 3.0%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.2%) TrueClass#===: 235,771 ( 2.2%) FalseClass#===: 231,144 ( 2.2%) Array#include?: 211,386 ( 2.0%) Hash#fetch: 204,702 ( 1.9%) Kernel#block_given?: 191,665 ( 1.8%) Kernel#dup: 179,348 ( 1.7%) BasicObject#!=: 176,181 ( 1.6%) String.new: 166,696 ( 1.6%) Kernel#kind_of?: 165,634 ( 1.5%) String#==: 163,678 ( 1.5%) Process.clock_gettime: 144,992 ( 1.4%) Array#any?: 138,310 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 72,324): cfunc: 48,057 (66.4%) iseq: 24,267 (33.6%) Top-6 not optimized method types for send_without_block (100.0% of total 4,523,699): iseq: 2,271,952 (50.2%) bmethod: 985,636 (21.8%) optimized: 949,704 (21.0%) alias: 310,747 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,293,340): invokesuper: 2,373,561 (55.3%) invokeblock: 811,934 (18.9%) sendforward: 505,452 (11.8%) opt_eq: 451,756 (10.5%) opt_plus: 74,406 ( 1.7%) opt_minus: 36,228 ( 0.8%) opt_send_without_block: 21,792 ( 0.5%) opt_neq: 7,231 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,753 ( 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,481,476): send_without_block_polymorphic: 9,722,801 (38.2%) send_no_profiles: 5,894,799 (23.1%) send_without_block_not_optimized_method_type: 4,523,699 (17.8%) not_optimized_instruction: 4,293,340 (16.8%) send_without_block_no_profiles: 948,985 ( 3.7%) send_not_optimized_method_type: 72,324 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,765 ( 0.0%) send_without_block_direct_too_many_args: 629 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 690,957): expandarray: 328,491 (47.5%) checkkeyword: 190,694 (27.6%) getclassvariable: 59,907 ( 8.7%) invokesuperforward: 49,503 ( 7.2%) getblockparam: 49,119 ( 7.1%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 952 ( 0.1%) checkmatch: 290 ( 0.0%) once: 23 ( 0.0%) Top-3 compile error reasons (100.0% of total 3,718,841): register_spill_on_alloc: 3,418,472 (91.9%) register_spill_on_ccall: 182,023 ( 4.9%) exception_handler: 118,346 ( 3.2%) Top-17 side exit reasons (100.0% of total 10,861,013): compile_error: 3,718,841 (34.2%) guard_type_failure: 2,638,940 (24.3%) guard_shape_failure: 1,917,541 (17.7%) unhandled_yarv_insn: 690,957 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 535,789 ( 4.9%) unhandled_kwarg: 455,351 ( 4.2%) unknown_newarray_send: 314,786 ( 2.9%) patchpoint_stable_constant_names: 235,507 ( 2.2%) unhandled_splat: 122,071 ( 1.1%) patchpoint_no_singleton_class: 109,668 ( 1.0%) unhandled_hir_insn: 76,397 ( 0.7%) patchpoint_method_redefined: 21,598 ( 0.2%) block_param_proxy_modified: 19,193 ( 0.2%) patchpoint_no_ep_escape: 3,765 ( 0.0%) obj_to_string_fallback: 568 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 19 ( 0.0%) send_count: 68,205,150 dynamic_send_count: 25,481,476 (37.4%) optimized_send_count: 42,723,674 (62.6%) iseq_optimized_send_count: 18,588,101 (27.3%) inline_cfunc_optimized_send_count: 13,566,855 (19.9%) non_variadic_cfunc_optimized_send_count: 7,904,518 (11.6%) variadic_cfunc_optimized_send_count: 2,664,200 ( 3.9%) dynamic_getivar_count: 7,366,650 dynamic_setivar_count: 7,245,122 compiled_iseq_count: 4,796 failed_iseq_count: 447 compile_time: 778ms profile_time: 9ms gc_time: 11ms invalidation_time: 77ms vm_write_pc_count: 63,636,742 vm_write_sp_count: 62,292,946 vm_write_locals_count: 62,292,946 vm_write_stack_count: 62,292,946 vm_write_to_parent_iseq_local_count: 292,458 vm_read_from_parent_iseq_local_count: 6,600,017 code_region_bytes: 22,970,368 side_exit_count: 10,861,013 total_insn_count: 517,633,620 vm_insn_count: 162,995,567 zjit_insn_count: 354,638,053 ratio_in_zjit: 68.5% ``` </details> lobsters after: <details> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (61.1% of total 10,239,008): Kernel#is_a?: 1,030,914 (10.1%) String#<<: 851,954 ( 8.3%) Hash#[]=: 742,942 ( 7.3%) Regexp#match?: 376,144 ( 3.7%) Hash#key?: 349,147 ( 3.4%) String#start_with?: 334,963 ( 3.3%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.3%) TrueClass#===: 235,771 ( 2.3%) FalseClass#===: 231,144 ( 2.3%) Array#include?: 211,386 ( 2.1%) Hash#fetch: 204,702 ( 2.0%) Kernel#block_given?: 181,797 ( 1.8%) Kernel#dup: 179,341 ( 1.8%) BasicObject#!=: 175,997 ( 1.7%) String.new: 166,696 ( 1.6%) Kernel#kind_of?: 165,600 ( 1.6%) String#==: 157,751 ( 1.5%) Process.clock_gettime: 144,992 ( 1.4%) Array#any?: 138,311 ( 1.4%) Set#include?: 134,362 ( 1.3%) Top-20 not annotated C methods (62.2% of total 10,372,753): Kernel#is_a?: 1,212,805 (11.7%) String#<<: 851,954 ( 8.2%) Hash#[]=: 743,121 ( 7.2%) Regexp#match?: 376,144 ( 3.6%) Hash#key?: 349,147 ( 3.4%) String#start_with?: 334,963 ( 3.2%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.3%) TrueClass#===: 235,771 ( 2.3%) FalseClass#===: 231,144 ( 2.2%) Array#include?: 211,386 ( 2.0%) Hash#fetch: 204,702 ( 2.0%) Kernel#block_given?: 191,666 ( 1.8%) Kernel#dup: 179,348 ( 1.7%) BasicObject#!=: 176,181 ( 1.7%) String.new: 166,696 ( 1.6%) Kernel#kind_of?: 165,634 ( 1.6%) String#==: 163,683 ( 1.6%) Process.clock_gettime: 144,992 ( 1.4%) Array#any?: 138,311 ( 1.3%) Integer#<=>: 135,056 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 72,324): cfunc: 48,057 (66.4%) iseq: 24,267 (33.6%) Top-6 not optimized method types for send_without_block (100.0% of total 4,523,699): iseq: 2,271,952 (50.2%) bmethod: 985,636 (21.8%) optimized: 949,704 (21.0%) alias: 310,747 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,293,339): invokesuper: 2,373,561 (55.3%) invokeblock: 811,933 (18.9%) sendforward: 505,452 (11.8%) opt_eq: 451,756 (10.5%) opt_plus: 74,406 ( 1.7%) opt_minus: 36,228 ( 0.8%) opt_send_without_block: 21,792 ( 0.5%) opt_neq: 7,231 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,753 ( 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,457,719): send_without_block_polymorphic: 9,699,046 (38.1%) send_no_profiles: 5,894,798 (23.2%) send_without_block_not_optimized_method_type: 4,523,699 (17.8%) not_optimized_instruction: 4,293,339 (16.9%) send_without_block_no_profiles: 948,985 ( 3.7%) send_not_optimized_method_type: 72,324 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,765 ( 0.0%) send_without_block_direct_too_many_args: 629 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 690,957): expandarray: 328,491 (47.5%) checkkeyword: 190,694 (27.6%) getclassvariable: 59,907 ( 8.7%) invokesuperforward: 49,503 ( 7.2%) getblockparam: 49,119 ( 7.1%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 952 ( 0.1%) checkmatch: 290 ( 0.0%) once: 23 ( 0.0%) Top-3 compile error reasons (100.0% of total 3,706,981): register_spill_on_alloc: 3,406,595 (91.9%) register_spill_on_ccall: 182,023 ( 4.9%) exception_handler: 118,363 ( 3.2%) Top-17 side exit reasons (100.0% of total 10,837,266): compile_error: 3,706,981 (34.2%) guard_type_failure: 2,638,921 (24.4%) guard_shape_failure: 1,917,552 (17.7%) unhandled_yarv_insn: 690,957 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 535,789 ( 4.9%) unhandled_kwarg: 455,351 ( 4.2%) unknown_newarray_send: 314,786 ( 2.9%) patchpoint_stable_constant_names: 223,630 ( 2.1%) unhandled_splat: 122,071 ( 1.1%) patchpoint_no_singleton_class: 109,668 ( 1.0%) unhandled_hir_insn: 76,397 ( 0.7%) patchpoint_method_redefined: 21,598 ( 0.2%) block_param_proxy_modified: 19,193 ( 0.2%) patchpoint_no_ep_escape: 3,765 ( 0.0%) obj_to_string_fallback: 568 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) interrupt: 17 ( 0.0%) send_count: 68,157,710 dynamic_send_count: 25,457,719 (37.4%) optimized_send_count: 42,699,991 (62.6%) iseq_optimized_send_count: 18,588,067 (27.3%) inline_cfunc_optimized_send_count: 13,872,916 (20.4%) non_variadic_cfunc_optimized_send_count: 7,904,566 (11.6%) variadic_cfunc_optimized_send_count: 2,334,442 ( 3.4%) dynamic_getivar_count: 7,342,896 dynamic_setivar_count: 7,245,126 compiled_iseq_count: 4,796 failed_iseq_count: 447 compile_time: 791ms profile_time: 9ms gc_time: 9ms invalidation_time: 68ms vm_write_pc_count: 63,283,243 vm_write_sp_count: 61,939,447 vm_write_locals_count: 61,939,447 vm_write_stack_count: 61,939,447 vm_write_to_parent_iseq_local_count: 292,458 vm_read_from_parent_iseq_local_count: 6,576,263 code_region_bytes: 22,872,064 side_exit_count: 10,837,266 total_insn_count: 517,075,555 vm_insn_count: 162,674,783 zjit_insn_count: 354,400,772 ratio_in_zjit: 68.5% ``` </details> --------- Co-authored-by: Max Bernstein <ruby@bernsteinbear.com>
2025-10-17ZJIT: Don't push frame for Hash#size (#14871)Jacob
`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>
2025-10-17ZJIT: Don't push frame for String#empty? (#14836)Jacob
lobsters before: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (71.9% of total 15,247,103): Hash#[]: 4,516,006 (29.6%) Class#current: 1,154,273 ( 7.6%) Kernel#is_a?: 1,027,952 ( 6.7%) Regexp#match?: 398,256 ( 2.6%) String#empty?: 353,775 ( 2.3%) Hash#key?: 349,154 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.5%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,339 ( 1.4%) Hash#fetch: 204,702 ( 1.3%) Kernel#block_given?: 181,789 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,336 ( 1.2%) BasicObject#!=: 174,429 ( 1.1%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,600 ( 1.1%) Top-20 not annotated C methods (72.5% of total 15,409,355): Hash#[]: 4,516,016 (29.3%) Kernel#is_a?: 1,209,970 ( 7.9%) Class#current: 1,154,273 ( 7.5%) Regexp#match?: 398,256 ( 2.6%) String#empty?: 361,013 ( 2.3%) Hash#key?: 349,154 ( 2.3%) Hash#[]=: 344,347 ( 2.2%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.5%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,339 ( 1.4%) Hash#fetch: 204,702 ( 1.3%) Kernel#block_given?: 191,658 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,343 ( 1.2%) BasicObject#!=: 174,613 ( 1.1%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,634 ( 1.1%) Top-2 not optimized method types for send (100.0% of total 71,083): cfunc: 47,637 (67.0%) iseq: 23,446 (33.0%) Top-6 not optimized method types for send_without_block (100.0% of total 4,482,446): iseq: 2,227,443 (49.7%) bmethod: 985,679 (22.0%) optimized: 952,914 (21.3%) alias: 310,750 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,264,922): invokesuper: 2,346,296 (55.0%) invokeblock: 809,163 (19.0%) sendforward: 505,446 (11.9%) opt_eq: 454,244 (10.7%) opt_plus: 74,059 ( 1.7%) opt_minus: 36,227 ( 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 27,366,538): send_without_block_polymorphic: 9,222,828 (33.7%) send_no_profiles: 5,892,897 (21.5%) send_without_block_not_optimized_method_type: 4,482,446 (16.4%) not_optimized_instruction: 4,264,922 (15.6%) send_without_block_no_profiles: 3,407,046 (12.4%) send_not_optimized_method_type: 71,083 ( 0.3%) send_without_block_cfunc_array_variadic: 15,135 ( 0.1%) obj_to_string_not_string: 9,919 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 688,292): expandarray: 328,369 (47.7%) checkkeyword: 190,697 (27.7%) getclassvariable: 59,286 ( 8.6%) getblockparam: 48,651 ( 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,675,808): register_spill_on_alloc: 3,459,950 (94.1%) register_spill_on_ccall: 215,858 ( 5.9%) Top-14 side exit reasons (100.0% of total 10,732,532): compile_error: 3,675,808 (34.2%) guard_type_failure: 2,616,693 (24.4%) guard_shape_failure: 1,902,102 (17.7%) unhandled_yarv_insn: 688,292 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 534,943 ( 5.0%) unhandled_kwarg: 421,996 ( 3.9%) patchpoint: 359,831 ( 3.4%) unknown_newarray_send: 314,665 ( 2.9%) unhandled_splat: 121,910 ( 1.1%) unhandled_hir_insn: 76,393 ( 0.7%) block_param_proxy_modified: 19,193 ( 0.2%) interrupt: 528 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 66,343,482 dynamic_send_count: 27,366,538 (41.2%) optimized_send_count: 38,976,944 (58.8%) iseq_optimized_send_count: 17,935,768 (27.0%) inline_cfunc_optimized_send_count: 5,794,073 ( 8.7%) non_variadic_cfunc_optimized_send_count: 12,588,582 (19.0%) variadic_cfunc_optimized_send_count: 2,658,521 ( 4.0%) dynamic_getivar_count: 7,321,990 dynamic_setivar_count: 7,231,183 compiled_iseq_count: 4,770 failed_iseq_count: 468 compile_time: 7,466ms profile_time: 52ms gc_time: 33ms invalidation_time: 116ms vm_write_pc_count: 64,768,186 vm_write_sp_count: 63,445,066 vm_write_locals_count: 63,445,066 vm_write_stack_count: 63,445,066 vm_write_to_parent_iseq_local_count: 292,445 vm_read_from_parent_iseq_local_count: 6,461,354 code_region_bytes: 22,446,080 side_exit_count: 10,732,532 total_insn_count: 515,600,654 vm_insn_count: 163,640,874 zjit_insn_count: 351,959,780 ratio_in_zjit: 68.3% ``` lobsters after: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (72.3% of total 14,893,304): Hash#[]: 4,515,997 (30.3%) Class#current: 1,154,273 ( 7.8%) Kernel#is_a?: 1,027,957 ( 6.9%) Regexp#match?: 398,259 ( 2.7%) Hash#key?: 349,149 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.3%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.6%) FalseClass#===: 231,144 ( 1.6%) Array#include?: 211,333 ( 1.4%) Hash#fetch: 204,703 ( 1.4%) Kernel#block_given?: 181,781 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,337 ( 1.2%) BasicObject#!=: 174,429 ( 1.2%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,600 ( 1.1%) String#==: 154,751 ( 1.0%) Top-20 not annotated C methods (72.9% of total 15,048,318): Hash#[]: 4,516,007 (30.0%) Kernel#is_a?: 1,209,975 ( 8.0%) Class#current: 1,154,273 ( 7.7%) Regexp#match?: 398,259 ( 2.6%) Hash#key?: 349,149 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.6%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,333 ( 1.4%) Hash#fetch: 204,703 ( 1.4%) Kernel#block_given?: 191,650 ( 1.3%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,344 ( 1.2%) BasicObject#!=: 174,613 ( 1.2%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,634 ( 1.1%) String#==: 160,682 ( 1.1%) 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,482,444): iseq: 2,227,440 (49.7%) bmethod: 985,679 (22.0%) optimized: 952,916 (21.3%) alias: 310,749 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,264,913): invokesuper: 2,346,301 (55.0%) invokeblock: 809,153 (19.0%) sendforward: 505,445 (11.9%) opt_eq: 454,244 (10.7%) opt_plus: 74,056 ( 1.7%) opt_minus: 36,227 ( 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 27,366,491): send_without_block_polymorphic: 9,222,820 (33.7%) send_no_profiles: 5,892,885 (21.5%) send_without_block_not_optimized_method_type: 4,482,444 (16.4%) not_optimized_instruction: 4,264,913 (15.6%) send_without_block_no_profiles: 3,407,030 (12.4%) send_not_optimized_method_type: 71,084 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,919 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 688,291): expandarray: 328,368 (47.7%) checkkeyword: 190,697 (27.7%) getclassvariable: 59,286 ( 8.6%) getblockparam: 48,651 ( 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,675,807): register_spill_on_alloc: 3,459,949 (94.1%) register_spill_on_ccall: 215,858 ( 5.9%) Top-14 side exit reasons (100.0% of total 10,732,546): compile_error: 3,675,807 (34.2%) guard_type_failure: 2,616,699 (24.4%) guard_shape_failure: 1,902,100 (17.7%) unhandled_yarv_insn: 688,291 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 534,950 ( 5.0%) unhandled_kwarg: 421,993 ( 3.9%) patchpoint: 359,837 ( 3.4%) unknown_newarray_send: 314,667 ( 2.9%) unhandled_splat: 121,913 ( 1.1%) unhandled_hir_insn: 76,393 ( 0.7%) block_param_proxy_modified: 19,193 ( 0.2%) interrupt: 525 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 66,343,388 dynamic_send_count: 27,366,491 (41.2%) optimized_send_count: 38,976,897 (58.8%) iseq_optimized_send_count: 17,935,730 (27.0%) inline_cfunc_optimized_send_count: 6,147,863 ( 9.3%) non_variadic_cfunc_optimized_send_count: 12,234,780 (18.4%) variadic_cfunc_optimized_send_count: 2,658,524 ( 4.0%) dynamic_getivar_count: 7,321,987 dynamic_setivar_count: 7,231,160 compiled_iseq_count: 4,770 failed_iseq_count: 468 compile_time: 7,223ms profile_time: 51ms gc_time: 32ms invalidation_time: 107ms vm_write_pc_count: 64,414,293 vm_write_sp_count: 63,091,183 vm_write_locals_count: 63,091,183 vm_write_stack_count: 63,091,183 vm_write_to_parent_iseq_local_count: 292,443 vm_read_from_parent_iseq_local_count: 6,461,326 code_region_bytes: 22,446,080 side_exit_count: 10,732,546 total_insn_count: 515,600,823 vm_insn_count: 163,641,263 zjit_insn_count: 351,959,560 ratio_in_zjit: 68.3% ```
2025-10-16ZJIT: Add to counters when FnProperties.inline inlining succeedsMax Bernstein
This counts methods that can be folded away to nothing *in addition* to the already-counted `CCall`.
2025-10-16ZJIT: Fix singleton class qualified method names in statsMax Bernstein
Now methods on singleton classes (for example, `new`) get split up into `String*#new`, `Array*#new`, ... (where the `*` indicates a singleton class) instead of all looking like `Class#new`. before: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (59.8% of total 10,506,888): String#<<: 987,752 ( 9.4%) Kernel#is_a?: 755,223 ( 7.2%) Hash#[]=: 700,802 ( 6.7%) Regexp#match?: 400,129 ( 3.8%) String#empty?: 353,775 ( 3.4%) String#start_with?: 334,961 ( 3.2%) Hash#key?: 331,080 ( 3.2%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.3%) TrueClass#===: 235,771 ( 2.2%) FalseClass#===: 231,144 ( 2.2%) Array#include?: 213,362 ( 2.0%) Kernel#respond_to?: 198,730 ( 1.9%) Kernel#dup: 178,920 ( 1.7%) Kernel#block_given?: 178,767 ( 1.7%) BasicObject#!=: 170,602 ( 1.6%) Class#new: 168,079 ( 1.6%) Kernel#kind_of?: 165,600 ( 1.6%) String#==: 158,036 ( 1.5%) Module#clock_gettime: 144,992 ( 1.4%) NilClass#===: 137,833 ( 1.3%) ``` after: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (59.8% of total 10,506,906): String#<<: 987,752 ( 9.4%) Kernel#is_a?: 755,237 ( 7.2%) Hash#[]=: 700,802 ( 6.7%) Regexp#match?: 400,129 ( 3.8%) String#empty?: 353,775 ( 3.4%) String#start_with?: 334,961 ( 3.2%) Hash#key?: 331,080 ( 3.2%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 2.3%) TrueClass#===: 235,771 ( 2.2%) FalseClass#===: 231,144 ( 2.2%) Array#include?: 213,362 ( 2.0%) Kernel#respond_to?: 198,730 ( 1.9%) Kernel#dup: 178,920 ( 1.7%) Kernel#block_given?: 178,767 ( 1.7%) BasicObject#!=: 170,602 ( 1.6%) String*#new: 166,696 ( 1.6%) Kernel#kind_of?: 165,600 ( 1.6%) String#==: 158,039 ( 1.5%) Process*#clock_gettime: 144,992 ( 1.4%) NilClass#===: 137,833 ( 1.3%) ```
2025-10-16ZJIT: Break out patchpoint exit reasons (#14858)Max Bernstein
We have a lot of patchpoint exits on some applications and this helps pin down why.
2025-10-16ZJIT: Inline BasicObject#initialize (#14856)Max Bernstein
It just returns nil.
2025-10-15ZJIT: Profile opt_succ and inline Integer#succ for Fixnum (#14846)Max Bernstein
This is only really called a lot in the benchmark harness, as far as I can tell.
2025-10-16ZJIT: Inline String#getbyte (#14842)Max Bernstein
2025-10-15ZJIT: Rewrite arm64_split_with_scratch_reg for clarityAiden Fox Ivey
* The while loop pattern can be rewritten to be more idiomatic, which also allows the iterator to no longer be mutable.
2025-10-15ZJIT: Use rb_gc_disable() over rb_gc_disable_no_rest()Alan Wu
no_rest() trips an assert inside the GC when we allocate with the GC disabled this way: (gc_continue) ../src/gc/default/default.c:2029 (newobj_cache_miss+0x128) [0x105040048] ../src/gc/default/default.c:2370 (rb_gc_impl_new_obj+0x7c) [0x105036374] ../src/gc/default/default.c:2482 (newobj_of) ../src/gc.c:995 (rb_method_entry_alloc+0x40) [0x1051e6c64] ../src/vm_method.c:1102 (rb_method_entry_complement_defined_class) ../src/vm_method.c:1180 (prepare_callable_method_entry+0x14c) [0x1051e87b8] ../src/vm_method.c:1728 (callable_method_entry_or_negative+0x1e8) [0x1051e809c] ../src/vm_method.c:1874 It's tries to continue the GC because it was out of space. Looks like it's not safe to allocate new objects after using rb_gc_disable_no_rest(); existing usages use it for malloc calls.
2025-10-15ZJIT: Add HashAref to HIR and inline Hash#[] to HashAref (#14838)Aiden Fox Ivey
Fixes https://github.com/Shopify/ruby/issues/793 ## Testing on `liquid-render`: <details> <summary>Before patch:</summary> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (96.8% of total 20,222,783): Kernel#respond_to?: 9,725,886 (48.1%) Hash#key?: 4,589,528 (22.7%) Set#include?: 1,493,789 ( 7.4%) String#===: 616,183 ( 3.0%) Hash#[]: 453,675 ( 2.2%) String#<<: 386,831 ( 1.9%) Integer#<<: 319,768 ( 1.6%) Kernel#is_a?: 312,176 ( 1.5%) Integer#/: 238,502 ( 1.2%) Kernel#format: 238,502 ( 1.2%) Array#<<: 220,724 ( 1.1%) Class#last_match: 179,182 ( 0.9%) Hash#[]=: 167,728 ( 0.8%) CGI::EscapeExt#escapeHTML: 106,471 ( 0.5%) Array#shift: 98,030 ( 0.5%) Array#unshift: 90,851 ( 0.4%) String#=~: 90,637 ( 0.4%) String#start_with?: 88,122 ( 0.4%) Regexp#===: 85,648 ( 0.4%) String#empty?: 80,950 ( 0.4%) Top-20 not annotated C methods (97.0% of total 20,268,253): Kernel#respond_to?: 9,725,886 (48.0%) Hash#key?: 4,589,528 (22.6%) Set#include?: 1,493,789 ( 7.4%) String#===: 616,183 ( 3.0%) Hash#[]: 453,675 ( 2.2%) Kernel#is_a?: 397,366 ( 2.0%) String#<<: 386,831 ( 1.9%) Integer#<<: 319,768 ( 1.6%) Integer#/: 238,502 ( 1.2%) Kernel#format: 238,502 ( 1.2%) Array#<<: 220,724 ( 1.1%) Class#last_match: 179,182 ( 0.9%) Hash#[]=: 167,728 ( 0.8%) CGI::EscapeExt#escapeHTML: 106,471 ( 0.5%) Array#shift: 98,030 ( 0.5%) Array#unshift: 90,851 ( 0.4%) String#=~: 90,637 ( 0.4%) String#start_with?: 88,122 ( 0.4%) Regexp#===: 85,648 ( 0.4%) String#empty?: 80,950 ( 0.4%) Top-2 not optimized method types for send (100.0% of total 1,180): iseq: 602 (51.0%) cfunc: 578 (49.0%) Top-3 not optimized method types for send_without_block (100.0% of total 4,896,785): iseq: 4,669,764 (95.4%) optimized: 227,001 ( 4.6%) alias: 20 ( 0.0%) Top-9 not optimized instructions (100.0% of total 1,255,287): invokeblock: 430,174 (34.3%) opt_neq: 319,471 (25.5%) opt_and: 319,471 (25.5%) opt_eq: 127,926 (10.2%) opt_le: 31,238 ( 2.5%) invokesuper: 23,409 ( 1.9%) opt_minus: 2,934 ( 0.2%) opt_send_without_block: 562 ( 0.0%) opt_or: 102 ( 0.0%) Top-7 send fallback reasons (100.0% of total 17,930,659): send_no_profiles: 6,145,096 (34.3%) send_without_block_polymorphic: 5,459,600 (30.4%) send_without_block_not_optimized_method_type: 4,896,785 (27.3%) not_optimized_instruction: 1,255,287 ( 7.0%) send_without_block_no_profiles: 170,037 ( 0.9%) obj_to_string_not_string: 2,674 ( 0.0%) send_not_optimized_method_type: 1,180 ( 0.0%) Top-3 unhandled YARV insns (100.0% of total 157,831): getclassvariable: 157,694 (99.9%) once: 121 ( 0.1%) getconstant: 16 ( 0.0%) Top-2 compile error reasons (100.0% of total 8,905,991): register_spill_on_alloc: 8,905,891 (100.0%) register_spill_on_ccall: 100 ( 0.0%) Top-9 side exit reasons (100.0% of total 26,549,652): compile_error: 8,905,991 (33.5%) guard_shape_failure: 6,590,116 (24.8%) guard_type_failure: 4,882,217 (18.4%) unhandled_splat: 4,150,547 (15.6%) unhandled_kwarg: 1,827,728 ( 6.9%) unhandled_yarv_insn: 157,831 ( 0.6%) unhandled_hir_insn: 34,072 ( 0.1%) patchpoint: 1,100 ( 0.0%) block_param_proxy_not_iseq_or_ifunc: 50 ( 0.0%) send_count: 72,944,863 dynamic_send_count: 17,930,659 (24.6%) optimized_send_count: 55,014,204 (75.4%) iseq_optimized_send_count: 26,520,888 (36.4%) inline_cfunc_optimized_send_count: 8,270,533 (11.3%) non_variadic_cfunc_optimized_send_count: 9,344,065 (12.8%) variadic_cfunc_optimized_send_count: 10,878,718 (14.9%) dynamic_getivar_count: 2,171,396 dynamic_setivar_count: 1,737,553 compiled_iseq_count: 383 failed_iseq_count: 46 compile_time: 820ms profile_time: 4ms gc_time: 22ms invalidation_time: 0ms vm_write_pc_count: 71,973,068 vm_write_sp_count: 71,544,492 vm_write_locals_count: 71,544,492 vm_write_stack_count: 71,544,492 vm_write_to_parent_iseq_local_count: 1,070,897 vm_read_from_parent_iseq_local_count: 27,449,010 code_region_bytes: 2,113,536 side_exit_count: 26,549,652 total_insn_count: 908,528,764 vm_insn_count: 484,633,128 zjit_insn_count: 423,895,636 ratio_in_zjit: 46.7% ``` </details> <details> <summary>after patch:</summary> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (97.2% of total 19,769,108): Kernel#respond_to?: 9,725,886 (49.2%) Hash#key?: 4,589,528 (23.2%) Set#include?: 1,493,789 ( 7.6%) String#===: 616,183 ( 3.1%) String#<<: 386,831 ( 2.0%) Integer#<<: 319,768 ( 1.6%) Kernel#is_a?: 312,176 ( 1.6%) Integer#/: 238,502 ( 1.2%) Kernel#format: 238,502 ( 1.2%) Array#<<: 220,724 ( 1.1%) Class#last_match: 179,182 ( 0.9%) Hash#[]=: 167,728 ( 0.8%) CGI::EscapeExt#escapeHTML: 106,471 ( 0.5%) Array#shift: 98,030 ( 0.5%) Array#unshift: 90,851 ( 0.5%) String#=~: 90,637 ( 0.5%) String#start_with?: 88,122 ( 0.4%) Regexp#===: 85,648 ( 0.4%) String#empty?: 80,950 ( 0.4%) Array#push: 78,615 ( 0.4%) Top-20 not annotated C methods (97.4% of total 19,814,578): Kernel#respond_to?: 9,725,886 (49.1%) Hash#key?: 4,589,528 (23.2%) Set#include?: 1,493,789 ( 7.5%) String#===: 616,183 ( 3.1%) Kernel#is_a?: 397,366 ( 2.0%) String#<<: 386,831 ( 2.0%) Integer#<<: 319,768 ( 1.6%) Integer#/: 238,502 ( 1.2%) Kernel#format: 238,502 ( 1.2%) Array#<<: 220,724 ( 1.1%) Class#last_match: 179,182 ( 0.9%) Hash#[]=: 167,728 ( 0.8%) CGI::EscapeExt#escapeHTML: 106,471 ( 0.5%) Array#shift: 98,030 ( 0.5%) Array#unshift: 90,851 ( 0.5%) String#=~: 90,637 ( 0.5%) String#start_with?: 88,122 ( 0.4%) Regexp#===: 85,648 ( 0.4%) String#empty?: 80,950 ( 0.4%) Array#push: 78,615 ( 0.4%) Top-2 not optimized method types for send (100.0% of total 1,180): iseq: 602 (51.0%) cfunc: 578 (49.0%) Top-3 not optimized method types for send_without_block (100.0% of total 4,896,785): iseq: 4,669,764 (95.4%) optimized: 227,001 ( 4.6%) alias: 20 ( 0.0%) Top-9 not optimized instructions (100.0% of total 1,255,287): invokeblock: 430,174 (34.3%) opt_neq: 319,471 (25.5%) opt_and: 319,471 (25.5%) opt_eq: 127,926 (10.2%) opt_le: 31,238 ( 2.5%) invokesuper: 23,409 ( 1.9%) opt_minus: 2,934 ( 0.2%) opt_send_without_block: 562 ( 0.0%) opt_or: 102 ( 0.0%) Top-7 send fallback reasons (100.0% of total 17,930,659): send_no_profiles: 6,145,096 (34.3%) send_without_block_polymorphic: 5,459,600 (30.4%) send_without_block_not_optimized_method_type: 4,896,785 (27.3%) not_optimized_instruction: 1,255,287 ( 7.0%) send_without_block_no_profiles: 170,037 ( 0.9%) obj_to_string_not_string: 2,674 ( 0.0%) send_not_optimized_method_type: 1,180 ( 0.0%) Top-3 unhandled YARV insns (100.0% of total 157,831): getclassvariable: 157,694 (99.9%) once: 121 ( 0.1%) getconstant: 16 ( 0.0%) Top-2 compile error reasons (100.0% of total 8,905,991): register_spill_on_alloc: 8,905,891 (100.0%) register_spill_on_ccall: 100 ( 0.0%) Top-9 side exit reasons (100.0% of total 26,549,652): compile_error: 8,905,991 (33.5%) guard_shape_failure: 6,590,116 (24.8%) guard_type_failure: 4,882,217 (18.4%) unhandled_splat: 4,150,547 (15.6%) unhandled_kwarg: 1,827,728 ( 6.9%) unhandled_yarv_insn: 157,831 ( 0.6%) unhandled_hir_insn: 34,072 ( 0.1%) patchpoint: 1,100 ( 0.0%) block_param_proxy_not_iseq_or_ifunc: 50 ( 0.0%) send_count: 72,491,188 dynamic_send_count: 17,930,659 (24.7%) optimized_send_count: 54,560,529 (75.3%) iseq_optimized_send_count: 26,520,888 (36.6%) inline_cfunc_optimized_send_count: 8,270,533 (11.4%) non_variadic_cfunc_optimized_send_count: 8,890,390 (12.3%) variadic_cfunc_optimized_send_count: 10,878,718 (15.0%) dynamic_getivar_count: 2,171,396 dynamic_setivar_count: 1,737,553 compiled_iseq_count: 383 failed_iseq_count: 46 compile_time: 808ms profile_time: 4ms gc_time: 21ms invalidation_time: 0ms vm_write_pc_count: 71,973,068 vm_write_sp_count: 71,544,492 vm_write_locals_count: 71,544,492 vm_write_stack_count: 71,544,492 vm_write_to_parent_iseq_local_count: 1,070,897 vm_read_from_parent_iseq_local_count: 27,449,010 code_region_bytes: 2,097,152 side_exit_count: 26,549,652 total_insn_count: 908,528,764 vm_insn_count: 484,633,128 zjit_insn_count: 423,895,636 ratio_in_zjit: 46.7% ``` </details> ## Testing on `lobsters`: <details> <summary>Before patch:</summary> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (71.0% of total 28,729,305): Hash#[]: 8,490,837 (29.6%) Kernel#is_a?: 1,861,955 ( 6.5%) String#<<: 1,773,932 ( 6.2%) Hash#[]=: 1,159,328 ( 4.0%) Regexp#match?: 775,654 ( 2.7%) String#empty?: 724,503 ( 2.5%) Hash#key?: 691,233 ( 2.4%) Kernel#respond_to?: 608,714 ( 2.1%) TrueClass#===: 451,557 ( 1.6%) FalseClass#===: 442,907 ( 1.5%) Array#include?: 429,408 ( 1.5%) ActiveSupport::OrderedOptions#_get: 377,468 ( 1.3%) String#start_with?: 373,685 ( 1.3%) ObjectSpace::WeakKeyMap#[]: 356,664 ( 1.2%) Kernel#kind_of?: 349,451 ( 1.2%) Kernel#dup: 328,120 ( 1.1%) Class#new: 310,590 ( 1.1%) Kernel#block_given?: 307,113 ( 1.1%) String#==: 290,654 ( 1.0%) Hash#fetch: 290,533 ( 1.0%) Top-20 not annotated C methods (71.7% of total 29,033,802): Hash#[]: 8,490,847 (29.2%) Kernel#is_a?: 2,231,950 ( 7.7%) String#<<: 1,773,932 ( 6.1%) Hash#[]=: 1,159,507 ( 4.0%) Regexp#match?: 775,654 ( 2.7%) String#empty?: 739,580 ( 2.5%) Hash#key?: 691,233 ( 2.4%) Kernel#respond_to?: 608,714 ( 2.1%) TrueClass#===: 451,557 ( 1.6%) FalseClass#===: 442,907 ( 1.5%) Array#include?: 429,408 ( 1.5%) ActiveSupport::OrderedOptions#_get: 377,468 ( 1.3%) String#start_with?: 373,685 ( 1.3%) ObjectSpace::WeakKeyMap#[]: 356,664 ( 1.2%) Kernel#kind_of?: 349,486 ( 1.2%) Kernel#dup: 328,127 ( 1.1%) Kernel#block_given?: 327,655 ( 1.1%) Class#new: 310,590 ( 1.1%) String#==: 296,624 ( 1.0%) Hash#fetch: 290,533 ( 1.0%) Top-2 not optimized method types for send (100.0% of total 96,231): cfunc: 75,873 (78.8%) iseq: 20,358 (21.2%) Top-6 not optimized method types for send_without_block (100.0% of total 8,044,793): iseq: 4,034,262 (50.1%) bmethod: 1,757,537 (21.8%) optimized: 1,647,169 (20.5%) alias: 596,446 ( 7.4%) null: 8,161 ( 0.1%) cfunc: 1,218 ( 0.0%) Top-13 not optimized instructions (100.0% of total 7,507,191): invokesuper: 4,343,829 (57.9%) invokeblock: 1,323,655 (17.6%) sendforward: 842,491 (11.2%) opt_eq: 722,952 ( 9.6%) opt_plus: 145,599 ( 1.9%) opt_minus: 52,269 ( 0.7%) opt_send_without_block: 39,595 ( 0.5%) opt_neq: 15,048 ( 0.2%) opt_mult: 13,826 ( 0.2%) opt_or: 7,452 ( 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 45,075,567): send_without_block_polymorphic: 17,072,731 (37.9%) send_no_profiles: 10,490,735 (23.3%) send_without_block_not_optimized_method_type: 8,044,793 (17.8%) not_optimized_instruction: 7,507,191 (16.7%) send_without_block_no_profiles: 1,816,853 ( 4.0%) send_not_optimized_method_type: 96,231 ( 0.2%) send_without_block_cfunc_array_variadic: 31,156 ( 0.1%) obj_to_string_not_string: 15,303 ( 0.0%) send_without_block_direct_too_many_args: 574 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 1,279,306): expandarray: 660,222 (51.6%) checkkeyword: 316,124 (24.7%) getclassvariable: 119,678 ( 9.4%) getblockparam: 88,485 ( 6.9%) invokesuperforward: 78,843 ( 6.2%) opt_duparray_send: 14,149 ( 1.1%) getconstant: 1,496 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 6,508,618): register_spill_on_alloc: 6,162,701 (94.7%) register_spill_on_ccall: 345,917 ( 5.3%) Top-14 side exit reasons (100.0% of total 19,988,958): compile_error: 6,508,618 (32.6%) guard_type_failure: 5,255,050 (26.3%) guard_shape_failure: 3,698,481 (18.5%) unhandled_yarv_insn: 1,279,306 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 990,585 ( 5.0%) unhandled_kwarg: 801,146 ( 4.0%) unknown_newarray_send: 539,110 ( 2.7%) patchpoint: 496,826 ( 2.5%) unhandled_splat: 242,104 ( 1.2%) unhandled_hir_insn: 147,346 ( 0.7%) block_param_proxy_modified: 29,122 ( 0.1%) interrupt: 1,072 ( 0.0%) obj_to_string_fallback: 170 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 118,969,379 dynamic_send_count: 45,075,567 (37.9%) optimized_send_count: 73,893,812 (62.1%) iseq_optimized_send_count: 32,439,432 (27.3%) inline_cfunc_optimized_send_count: 12,725,075 (10.7%) non_variadic_cfunc_optimized_send_count: 24,121,279 (20.3%) variadic_cfunc_optimized_send_count: 4,608,026 ( 3.9%) dynamic_getivar_count: 13,002,365 dynamic_setivar_count: 12,402,229 compiled_iseq_count: 4,817 failed_iseq_count: 466 compile_time: 8,961ms profile_time: 68ms gc_time: 41ms invalidation_time: 288ms vm_write_pc_count: 113,940,194 vm_write_sp_count: 111,595,088 vm_write_locals_count: 111,595,088 vm_write_stack_count: 111,595,088 vm_write_to_parent_iseq_local_count: 514,997 vm_read_from_parent_iseq_local_count: 11,288,600 code_region_bytes: 22,970,368 side_exit_count: 19,988,958 total_insn_count: 928,321,939 vm_insn_count: 297,374,855 zjit_insn_count: 630,947,084 ratio_in_zjit: 68.0% ``` </details> <details> <summary>after patch:</summary> ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (60.9% of total 19,827,919): Kernel#is_a?: 1,827,297 ( 9.2%) String#<<: 1,764,393 ( 8.9%) Hash#[]=: 1,159,637 ( 5.8%) Regexp#match?: 775,625 ( 3.9%) String#empty?: 723,469 ( 3.6%) Hash#key?: 691,214 ( 3.5%) Kernel#respond_to?: 602,389 ( 3.0%) TrueClass#===: 447,671 ( 2.3%) FalseClass#===: 439,274 ( 2.2%) Array#include?: 425,491 ( 2.1%) Hash#fetch: 382,294 ( 1.9%) String#start_with?: 373,684 ( 1.9%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) Kernel#kind_of?: 340,341 ( 1.7%) Kernel#dup: 328,108 ( 1.7%) Class#new: 309,571 ( 1.6%) Kernel#block_given?: 307,098 ( 1.5%) String#==: 286,539 ( 1.4%) BasicObject#!=: 284,640 ( 1.4%) String#length: 256,345 ( 1.3%) Top-20 not annotated C methods (62.1% of total 20,127,933): Kernel#is_a?: 2,205,849 (11.0%) String#<<: 1,764,393 ( 8.8%) Hash#[]=: 1,159,816 ( 5.8%) Regexp#match?: 775,625 ( 3.9%) String#empty?: 738,546 ( 3.7%) Hash#key?: 691,214 ( 3.4%) Kernel#respond_to?: 602,389 ( 3.0%) TrueClass#===: 447,671 ( 2.2%) FalseClass#===: 439,274 ( 2.2%) Array#include?: 425,491 ( 2.1%) Hash#fetch: 382,294 ( 1.9%) String#start_with?: 373,684 ( 1.9%) ObjectSpace::WeakKeyMap#[]: 356,654 ( 1.8%) Kernel#kind_of?: 340,375 ( 1.7%) Kernel#dup: 328,115 ( 1.6%) Kernel#block_given?: 327,640 ( 1.6%) Class#new: 309,571 ( 1.5%) String#==: 292,509 ( 1.5%) BasicObject#!=: 284,824 ( 1.4%) String#length: 256,345 ( 1.3%) Top-2 not optimized method types for send (100.0% of total 113,430): cfunc: 75,863 (66.9%) iseq: 37,567 (33.1%) Top-6 not optimized method types for send_without_block (100.0% of total 8,005,732): iseq: 4,007,647 (50.1%) bmethod: 1,750,263 (21.9%) optimized: 1,647,088 (20.6%) alias: 591,356 ( 7.4%) null: 8,161 ( 0.1%) cfunc: 1,217 ( 0.0%) Top-13 not optimized instructions (100.0% of total 7,569,803): invokesuper: 4,320,589 (57.1%) invokeblock: 1,321,548 (17.5%) sendforward: 841,452 (11.1%) opt_eq: 811,601 (10.7%) opt_plus: 142,565 ( 1.9%) opt_minus: 52,268 ( 0.7%) opt_send_without_block: 42,982 ( 0.6%) opt_neq: 15,047 ( 0.2%) opt_mult: 13,824 ( 0.2%) opt_or: 7,452 ( 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 45,409,745): send_without_block_polymorphic: 17,360,049 (38.2%) send_no_profiles: 10,502,130 (23.1%) send_without_block_not_optimized_method_type: 8,005,732 (17.6%) not_optimized_instruction: 7,569,803 (16.7%) send_without_block_no_profiles: 1,811,570 ( 4.0%) send_not_optimized_method_type: 113,430 ( 0.2%) send_without_block_cfunc_array_variadic: 31,154 ( 0.1%) obj_to_string_not_string: 15,303 ( 0.0%) send_without_block_direct_too_many_args: 574 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 1,241,241): expandarray: 622,183 (50.1%) checkkeyword: 316,113 (25.5%) getclassvariable: 119,668 ( 9.6%) getblockparam: 88,481 ( 7.1%) invokesuperforward: 78,842 ( 6.4%) opt_duparray_send: 14,149 ( 1.1%) getconstant: 1,496 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 6,521,426): register_spill_on_alloc: 6,175,519 (94.7%) register_spill_on_ccall: 345,907 ( 5.3%) Top-14 side exit reasons (100.0% of total 19,869,193): compile_error: 6,521,426 (32.8%) guard_type_failure: 5,167,727 (26.0%) guard_shape_failure: 3,708,529 (18.7%) unhandled_yarv_insn: 1,241,241 ( 6.2%) block_param_proxy_not_iseq_or_ifunc: 990,130 ( 5.0%) unhandled_kwarg: 800,104 ( 4.0%) unknown_newarray_send: 539,105 ( 2.7%) patchpoint: 494,790 ( 2.5%) unhandled_splat: 229,423 ( 1.2%) unhandled_hir_insn: 147,342 ( 0.7%) block_param_proxy_modified: 28,111 ( 0.1%) interrupt: 1,073 ( 0.0%) obj_to_string_fallback: 170 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 109,972,903 dynamic_send_count: 45,409,745 (41.3%) optimized_send_count: 64,563,158 (58.7%) iseq_optimized_send_count: 32,205,906 (29.3%) inline_cfunc_optimized_send_count: 12,529,333 (11.4%) non_variadic_cfunc_optimized_send_count: 15,123,197 (13.8%) variadic_cfunc_optimized_send_count: 4,704,722 ( 4.3%) dynamic_getivar_count: 12,973,226 dynamic_setivar_count: 12,381,984 compiled_iseq_count: 4,816 failed_iseq_count: 467 compile_time: 8,116ms profile_time: 59ms gc_time: 35ms invalidation_time: 289ms vm_write_pc_count: 113,616,123 vm_write_sp_count: 111,273,109 vm_write_locals_count: 111,273,109 vm_write_stack_count: 111,273,109 vm_write_to_parent_iseq_local_count: 516,816 vm_read_from_parent_iseq_local_count: 11,255,225 code_region_bytes: 22,872,064 side_exit_count: 19,869,193 total_insn_count: 924,733,475 vm_insn_count: 296,183,588 zjit_insn_count: 628,549,887 ratio_in_zjit: 68.0% ``` </details>