Skip to content

Fall back to normal call path for non-symbol keyword keys - #9815

Open
sferik wants to merge 1 commit into
jruby:masterfrom
sferik:jit-braceless-hash-keywords
Open

sferik wants to merge 1 commit into
jruby:masterfrom
sferik:jit-braceless-hash-keywords

Conversation

@sferik

@sferik sferik commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

A call with a braceless hash argument whose key isn’t a plain symbol, such as h.merge("a" => 1), sets the keywords flag, but its last argument is a temporary variable, not a literal operands.Hash. The direct keyword-argument path in compileCallCommon (added in #9219) cast that argument to Hash anyway. The cast threw ClassCastException, so the method could never be JIT-compiled and ran in the interpreter for good.

This change takes the direct path only when the last argument is a literal hash whose keys are all symbols. Every other call goes through the normal call path, as it did in 10.0.7. Checking for a Hash alone isn’t enough, because compileCallWithKeywords also casts each key to Symbol.

The new spec in spec/compiler/general_spec.rb covers each failing form from the issue, a mixed positional/keyword call, and a call inside a block. Before this change it fails in JIT mode with the ClassCastException; after it, it passes in all four modes.

A call with a braceless hash argument whose key is not a plain symbol,
such as h.merge("a" => 1), set the keywords flag but did not pass a
literal symbol-keyed hash as its last argument. The direct keyword
path in compileCallCommon cast that argument to Hash anyway, so the
JIT threw ClassCastException and the method stayed interpreted.

Take the direct path only when the last argument is a literal hash
whose keys are all symbols, and use the normal call path otherwise.

Fixes jruby#9814
@sferik
sferik force-pushed the jit-braceless-hash-keywords branch from 39018e2 to d343166 Compare October 17, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant