Skip to content

Fix super chaining on Ruby subclasses of Java classes#6820

Merged
headius merged 6 commits intojruby:masterfrom
headius:fix_ruby_java_super_chaining
Sep 13, 2021
Merged

Fix super chaining on Ruby subclasses of Java classes#6820
headius merged 6 commits intojruby:masterfrom
headius:fix_ruby_java_super_chaining

Conversation

@headius
Copy link
Member

@headius headius commented Sep 10, 2021

The issue here was that we super calls would sometimes fall back on reflective invocation when more than one subclass was involved. This had the effect of restarting the invocation chain back at the bottom of the hierarchy (from the self object's class) due to the nature of reflective invocation (it always calls the lowest override).

The fix here pulls the super invocation logic back from within the Java integration guts and into the Ruby-level super logic, so we can look up an appropriate super shim method to invoke at the proper level.

This fix will need to be refined in the future, using some of the following ideas:

  • Rewrite such supers to be a different instruction. We should be able to detect this in the same way we detect super in the initialize methods of Ruby/Java subclasses. Alternatively make the check into a boolean, but this keeps some unnecessary overhead when the super invocation does not involve a Ruby/Java subclass.
  • Restructure JI invocation to be able to handle this case, by passing through the definingModule from which the super call should originate. This was not possible using the standard DynamicMethod call paths, but enhancement may be possible.
  • Improve the caching of this and other forms of super, which may inform a better design.

Includes simple test cases for the examples in #6718.

Fixes #6718.

Super method invocations from JRuby must use the generated super
shims in order to invoke the override at the correct level in the
class hierarchy. The previous logic fell back on standard
reflective invocation, which always starts at the bottom. This led
to the issues in jruby#6718 where the super call chain would get stuck
in a recursive loop and eventually blow the call stack. This
change moves the invocation logic closer to the Ruby super logic,
allowing us to retrieve the appropriate super shim method when
performing the invocation.

Fixes jruby#6718
@headius headius added this to the JRuby 9.3.0.0 milestone Sep 10, 2021
Every combination of three descendants with and without overrides.
@headius headius merged commit 97330ea into jruby:master Sep 13, 2021
@headius headius deleted the fix_ruby_java_super_chaining branch September 13, 2021 14:45
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.

Current 9.3.0.0 subchild not properly registering the override of a parent with the reification cf 9.2.18.0 and earlier version.

3 participants