Skip to content

Cache immutable literals in indy JIT - #9644

Draft
headius wants to merge 1 commit into
jruby:masterfrom
headius:cache_immutable_literals
Draft

headius wants to merge 1 commit into
jruby:masterfrom
headius:cache_immutable_literals

Conversation

@headius

@headius headius commented Sep 3, 2026 •

Copy link
Copy Markdown
Member

Immutable literal values like numerics and ranges can be created once globally and never constructed again. Without a global cache, however, both the IR and the JIT will potentially construct them more than once, even if those values may be locally cached. In addition, the IR optimizer will sometimes propagate immutable literal values through variables and copies making it appear that there are multiple of the same literal in a piece of code. This all combines to potentially create more instances of immutable literal values than the single global value actually needed.

This PR introduces a global cache for several immutable literal values using an object key and a weak-valued map. So long as one piece of code remains loaded and referencing a given value, it should not be recreated in duplicate operands or call sites. This cache acts as a sort of constant pool for these values.

@headius headius added this to the JRuby 10.1.2.0 milestone Sep 3, 2026
@headius
headius force-pushed the cache_immutable_literals branch 3 times, most recently from 079cf90 to 6c83f28 Compare September 4, 2026 01:03
Immutable literal values like numerics and ranges can be created
once globally and never constructed again. Without a global cache,
however, both the IR and the JIT will potentially construct them
more than once, even if those values may be locally cached. In
addition, the IR optimizer will sometimes propagate immutable
literal values through variables and copies making it appear that
there are multiple of the same literal in a piece of code. This all
combines to potentially create more instances of immutable literal
values than the single global value actually needed.

This PR introduces a global cache for several immutable literal
values using an object key and a weak-valued map. So long as one
piece of code remains loaded and referencing a given value, it
should not be recreated in duplicate operands or call sites. This
cache acts as a sort of constant pool for these values.
@headius
headius force-pushed the cache_immutable_literals branch from 6c83f28 to b8f89b9 Compare September 4, 2026 02:23
@headius

headius commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

This is a simple way to handle caching immutable literals but I need to run some tests to make sure it does not increase memory size. Where before there might have been two RubyFloat with the same value, now there will be one RubyFloat plus a Double key and a WeakReference holder along with whatever bookkeeping objects are required inside WeakValuedMap. For values repeated in many places, this will be a savings, but for values that only appear a few times in code, we may actually be using more memory.

@kares

kares commented Sep 4, 2026

Copy link
Copy Markdown
Member

what's the motivation behind this, does this matter in production apps?

@headius

headius commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

@kares I don't have an answer to that. I do know that it surfaced a bug when I started re-enabling non-indy test runs #9643. It is of debatable utility, though, which is why I commented above that the overhead of this system may not be worth any small benefit.

It is arguably similar to a constant pool, which JVM classes typically do on a per-classfile basis, or deduplicated Strings in the JVM. But at the JVM level they can implement weak caches much more efficiently.

@headius headius removed this from the JRuby 10.1.2.0 milestone Sep 10, 2026
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.

2 participants