You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@rwstauner and I spent some time tracking down a regex issue in a Rails app we’re running on TruffleRuby. It looks like a pathological case in regex caching. We have a Rails action that creates a new Regexp object via Regexp.union. When the Regexp is created TruffleRuby adds the RubyRegexp object to the RubyLanguage#regexpTable cache. Then when we create a TRegex object, we attach it to the cached RubyRegexp instance.
The problem is that RubyLanguage#regexpTable is a WeakValueCache and nothing is retaining a reference to these dynamically created RubyRegexp objects. That’s convenient for memory savings, but because the TRegex object is attached to the RubyRegexp object, when the RubyRegexp is purged from the cache we also lose the TRegex object. Since TRegex lazily builds its call target, this leads to a deopt when populating the local TRegex object cache. Consequently, we’re seeing a ton of deopts for the same Truffle::RegexpOperations.match_in_region split.
It looks like this could manifest in other ways as well. E.g., anywhere we call Truffle::Type.coerce_to_regexp (e.g., String#scan) could dynamically create a Regexp that will not be retained.
A contrived example that illustrates the problem is:
@rwstauner and I spent some time tracking down a regex issue in a Rails app we’re running on TruffleRuby. It looks like a pathological case in regex caching. We have a Rails action that creates a new
Regexp
object viaRegexp.union
. When theRegexp
is created TruffleRuby adds theRubyRegexp
object to theRubyLanguage#regexpTable
cache. Then when we create a TRegex object, we attach it to the cachedRubyRegexp
instance.The problem is that
RubyLanguage#regexpTable
is aWeakValueCache
and nothing is retaining a reference to these dynamically createdRubyRegexp
objects. That’s convenient for memory savings, but because the TRegex object is attached to theRubyRegexp
object, when theRubyRegexp
is purged from the cache we also lose the TRegex object. Since TRegex lazily builds its call target, this leads to a deopt when populating the local TRegex object cache. Consequently, we’re seeing a ton of deopts for the sameTruffle::RegexpOperations.match_in_region
split.It looks like this could manifest in other ways as well. E.g., anywhere we call
Truffle::Type.coerce_to_regexp
(e.g.,String#scan
) could dynamically create aRegexp
that will not be retained.A contrived example that illustrates the problem is:
In reality, the loop we're executing comes from access the same page repeatedly in a load test. The "loop body" in this case is the Rails action.
I've discussed this with @eregon on the GraalVM Slack.
The text was updated successfully, but these errors were encountered: