From: "jamescook83 (James Cook) via ruby-core" Date: 2026-11-13T18:32:22+00:00 Subject: [ruby-core:127472] [Ruby Bug#22546] YJIT panics in arm64 `add` when compiling a method with 495 or more locals Issue #22546 has been reported by jamescook83 (James Cook). ---------------------------------------- Bug #22546: YJIT panics in arm64 `add` when compiling a method with 495 or more locals https://bugs.ruby-lang.org/issues/22546 * Author: jamescook83 (James Cook) * Status: Open * ruby -v: ruby 4.1.0dev (2026-11-13 master acc624e47b) +PRISM [arm64-darwin25] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Versions: - ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [arm64-darwin25] - ruby 4.1.0dev (2026-11-13 master acc624e47b) +PRISM [arm64-darwin25] macOS on Apple silicon. Also reproduces on Linux: - ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [aarch64-linux] (`ruby:4.0.9-slim` Docker image, native arm64): same threshold, same panic at yjit/src/asm/arm64/mod.rs:53:78. - ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [x86_64-linux] (same image, x86_64 emulated with Rosetta on Apple silicon): a similar but different failure. 495 locals and up to 4089 compile and return correct values; at 4090 locals the process segfaults (exit 139) with no `[BUG]` output. Without `--yjit` it runs. Repro (run with `ruby --yjit`): ```ruby count = 600 body = (1..count).map { |n| " v#{n} = a + #{n}" }.join("\n") eval("def many_locals(a)\n#{body}\n v1\nend") 100.times { many_locals(1) } ``` A local table of 494 entries compiles; 495 panics, the same on both versions. Stack depth does not move it (300 locals with a 220-element array literal compiles). Without `--yjit` every count runs. The attached yjit_repro.rb bisects the threshold, running each count in a child `ruby --yjit`. Panic (4.1.0dev; 4.0.9 shows the same frames and the same line): ``` ruby: YJIT has panicked. More info to follow... thread '' panicked at ./yjit/src/asm/arm64/mod.rs:53:78: called `Result::unwrap()` on an `Err` value: () 3: yjit::asm::arm64::add 4: ::arm64_emit 5: ::compile_with_regs 6: ::compile 7: yjit::codegen::gen_single_block 8: yjit::core::gen_block_series 9: yjit::core::branch_stub_hit_body 12: yjit::core::branch_stub_hit [BUG] YJIT: panicked at ./yjit/src/asm/arm64/mod.rs:53:78 ``` Expected: no panic. ZJIT on the same 4.1.0dev build compiles these methods (with `--zjit-call-threshold=1`) and runs them correctly up to 2048 locals; at 5000 it declines to compile and the interpreter runs it. **Use case.** This came from a tool that compiles a small language to Ruby. Its output is long straight-line methods, and each intermediate result gets its own local, so one source function can produce a few hundred locals. Other generated code can reach similar counts: #22074 was found in production through a large Slim template with more than 256 locals. The method is valid Ruby and runs correctly in the interpreter, but under YJIT it aborts the whole process with `[BUG]`. Splitting the generated methods into smaller ones avoids it. The generator works around it now, but other generated code will hit the same limit. ---Files-------------------------------- yjit_repro.rb (1.24 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/