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

[ji] lazy loading of Java (proxy) class extensions #5161

Merged
merged 4 commits into from May 18, 2018
Merged

[ji] lazy loading of Java (proxy) class extensions #5161

merged 4 commits into from May 18, 2018

Conversation

kares
Copy link
Member

@kares kares commented May 10, 2018

  • seems to work fine to the limited testing that I did locally
  • the gist is - Java extensions load on demand as Java classes are (first) used
  • theoretically we could also add a flag to disable the laziness and behave as before

also ... we could safely add more extensions now and do not have to worry much about bloating load times

did not run any numbers yet, but hopefully we do not do much JI internally on gem list, rake etc

@kares kares added this to the JRuby 9.2.0.0 milestone May 13, 2018
@kares kares requested a review from headius May 13, 2018 17:50
@headius
Copy link
Member

headius commented May 13, 2018

No prob, will review. Have you managed to measure anything yet?

@kares
Copy link
Member Author

kares commented May 14, 2018

quick test of time bin/jruby -S gem list

# BEFORE:
 
real	0m1.823s
user	0m2.945s
sys	0m0.157s

real	0m1.778s
user	0m2.951s
sys	0m0.162s

real	0m1.769s
user	0m2.884s
sys	0m0.171s

AVG 1.79s


# AFTER 

real	0m1.739s
user	0m2.780s
sys	0m0.165s

real	0m1.736s
user	0m2.847s
sys	0m0.144s

real	0m1.712s
user	0m2.764s
sys	0m0.186s

AVG 1.73s

... gets us around 5% on my machine

Copy link
Member

@headius headius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The static reference needs to be fixed, and the naming is problematic, but otherwise this seems ok. I worry a bit about races but the logic that sets up the proxy class should be safe currently. Will request review from @enebo.

}

@JRubyModule(name = "Java::JavaLang::Iterable", include = "Enumerable")
public static class Iterable {

static RubyModule define(final Ruby runtime) {
final RubyModule Iterable = Java.getProxyClass(runtime, java.lang.Iterable.class);
static RubyModule define(final Ruby runtime, final RubyModule Iterable) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use a different name for these? I find it extremely confusing when I look at the code and I see "Iterable" meaning two different things.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that at this point in the code, Iterable now means three different things: the inner class, the variable, and (to me at a glance) the actual Java Iterable class. It's quite confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment applies to all other such names below. I understand that it might look a bit nicer to some, but this flies against typical Java local variable naming convention.

It's somewhat confusing that the extension classes have the same names as the Java class they extend, but that seems like less of an issue to me than the local variables having yet again the same name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, will take a look into that


private static final boolean IMMEDIATE = false;

private static final JavaExtensions INSTANCE = new JavaExtensions();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be static; a better place would be for it to live on the javasupport Java instance attached to the runtime.

It is weak on the value, but it also anchors a class as its key. The classes we currently extend are system-level classes, but this may be used in the future for classes loaded as part of JRuby or within extensions (e.g. jruby-openssl) that load into their own classloaders, and this reference will prevent them from being collected.

It also is not compatible with multiple JRuby instances in the same JVM, since only the first one will register (and eventually apply) an extension. The others will race to insert the extension or remove it when applying that extension.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh somehow my review used an older version that was still static. I see you have fixed that, thanks!

@headius headius requested a review from enebo May 14, 2018 20:55
@kares
Copy link
Member Author

kares commented May 15, 2018

The static reference needs to be fixed, and the naming is problematic, but otherwise this seems ok.

✔️

I worry a bit about races but the logic that sets up the proxy class should be safe currently

exactly - its plugged in right around proxy-class initialization which is already race condition tuned (some tests are in place)

assert previous == null;
}

public static void define(final Class javaClass, final RubyModule proxyClass) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like runtime could be a parameter here to match put().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also seems to line up more with Iterable stuff below which also have runtime.

Copy link
Member

@enebo enebo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me. I guess only fear is proxy class initialization concurrency, but that has not actually changed at all in this PR so seems fine.

@kares kares force-pushed the ji-lazy branch 2 times, most recently from 3325389 to ab086b7 Compare May 18, 2018 14:45
@kares kares merged commit 262bea3 into master May 18, 2018
@kares kares deleted the ji-lazy branch May 18, 2018 14:59
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.

None yet

3 participants