Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce overhead of binding Java classes and methods #5832

Merged
merged 12 commits into from Sep 16, 2019

Conversation

@headius
Copy link
Member

headius commented Aug 13, 2019

This is a work-in-progress to reduce the overhead of our initial setup and binding of Ruby proxy classes for Java classes.

There's a number of places in this binding logic where we re-scan or re-partition methods, as well as creating a large number of transient data objects that are thrown away once the class is bound. I will be trying to find a way to pipeline more of this process to avoid the intermediate state objects.

This reduces the amount of method scanning needed to boot up a
given class. The filtered ClassValues filter out methods that will
not be accessible, and then goes on to separate out the static
methods.
@headius headius force-pushed the headius:java_binding_optz branch from 31ece51 to 6b45d64 Aug 13, 2019
headius added 10 commits Aug 13, 2019
For classes which have no static methods to bind, this was
creating a map unnecessarily. There will never be classes that
have no instance methods (since they all eventually descend from
object) but the consistency seems better here.
For Map iteration, this avoids creating intermediate Set and
Iterator objects, plus all the transient Map.Entry objects. For
List iteration, this eliminates the Iterator. Both cases may
require allocating the lambda object and introduce boot-time
overhead to instantiate the lambda class, but overall this patch
should reduce allocation along these paths.
This may not improve load times since we only do this once for
each bound class, rather than doing it for classes in that bound
class's hierarchy.
Note it's not really lazy yet because RubyToJavaInvoker calls
initialize immediately and most upstream logic eagerly prepares
the payload.

This commit also removes the intermedate installer for
constructors.
* Avoid repeated security exceptions by caching empty method lists
* Localize more method-gathering state and logic into
  MethodGatherer class
* Clean up some visibility and organization.
@headius headius added this to the JRuby 9.2.9.0 milestone Aug 21, 2019
@headius headius merged commit 7c32098 into jruby:master Sep 16, 2019
4 checks passed
4 checks passed
jruby.jruby Build #20190821.6 succeeded
Details
jruby.jruby (Job linux) Job linux succeeded
Details
jruby.jruby (Job mac) Job mac succeeded
Details
jruby.jruby (Job windows) Job windows succeeded
Details
@headius headius deleted the headius:java_binding_optz branch Sep 16, 2019
headius added a commit to headius/jruby that referenced this pull request Nov 26, 2019
* Private classes were considered for method binding even though
  we no longer set them accessible on Java 9+ when they have not
  already been opened. This resulted in Java 9+ environments
  producing method errors when they attempted to dispatch to those
  methods on private classes.
* In order to fix the above for private classes with public
  interfaces, this patch also fixes how we traverse a class's
  implemented interfaces. Possibly from changes in jruby#5832, we were
  not walking an interface's superinterfaces, causing us to only
  walk one level in such cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

1 participant
You can’t perform that action at this time.