Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Reduce overhead of binding Java classes and methods #5832
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.
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.
* 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.