Feature #21553
closedRemove opt_aref_with and opt_aset_with instructions
Description
Hi,
I'd like to remove the opt_aref_with
and opt_aset_with
instructions. I think they are fairly rare these days. Removing them will simplify the YARV compiler, the JIT compilers, and fix an issue with warnings.
For background, these instructions are used with code like foo["bar"]
, but only when the string literal isn't frozen:
> ./miniruby --dump=insns -e'foo["bar"]'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)>
0000 putself ( 1)[Li]
0001 opt_send_without_block <calldata!mid:foo, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 opt_aref_with "bar", <calldata!mid:[], argc:1, ARGS_SIMPLE>
0006 leave
Enabling frozen string literals will use putobject
with opt_aref
:
> ./miniruby --dump=insns --enable=frozen-string-literal -e'foo["bar"]'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)>
0000 putself ( 1)[Li]
0001 opt_send_without_block <calldata!mid:foo, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 putobject "bar"
0005 opt_aref <calldata!mid:[], argc:1, ARGS_SIMPLE>[CcCr]
0007 leave
The optimization avoids duping the string if the receiver happens to be a hash. I tested this with YJIT benchmarks and didn't see any impact. To be sure, I checked the lobsters benchmark to find uses of this instruction, and I found it was only used 4 times during any particular request which explained why removing the instruction didn't impact runtime performance.
Also, removing these instructions fixes a bug where a "chilled string warning" won't show up.
For example:
class Foo
def self.[](x)= x.gsub!(/hello/, "hi")
end
Foo["hello world"]
I would expect to see a "chilled string" warning with this code, but no warning shows up. Removing these instructions makes the warning show up as expected.
I sent a patch to remove the instructions here: https://github.com/ruby/ruby/pull/14336
Updated by tenderlovemaking (Aaron Patterson) 7 days ago
- Tracker changed from Bug to Feature
- Backport deleted (
3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN)
Updated by ko1 (Koichi Sasada) 6 days ago
· Edited
no problem.
(I didn't introduce these instructions so I'm not sure I can say Okay...)
Updated by tenderlovemaking (Aaron Patterson) 6 days ago
- Status changed from Open to Closed
Applied in changeset git|fb6e3a80009a744a4e0b75660f1ce6da65e20e6c.
Remove opt_aref_with
and opt_aset_with
When these instructions were introduced it was common to read from a
hash with mutable string literals. However, these days, I think these
instructions are fairly rare.
I tested this with the lobsters benchmark, and saw no difference in
speed. In order to be sure, I tracked down every use of this
instruction in the lobsters benchmark, and there were only 4 places
where it was used.
Additionally, this patch fixes a case where "chilled strings" should
emit a warning but they don't.
class Foo
def self.[](x)= x.gsub!(/hello/, "hi")
end
Foo["hello world"]
Removing these instructions shows this warning:
> ./miniruby -vw test.rb
ruby 3.5.0dev (2025-08-25T21:36:50Z rm-opt_aref_with dca08e286c) +PRISM [arm64-darwin24]
test.rb:2: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
[Feature #21553]
Updated by k0kubun (Takashi Kokubun) 6 days ago
· Edited
I didn't introduce these instructions
ref: [Bug #9382], 58f800a278b8b70463f4afdbb23a918d8ab441ff
Updated by k0kubun (Takashi Kokubun) 6 days ago
- Related to Bug #9382: [patch] add opt_aref_str and opt_aset_str added