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

[GR-38070] Share reflection invocation stubs with same signature. #4517

Merged
merged 3 commits into from
Apr 28, 2022

Conversation

graalvmbot
Copy link
Collaborator

This PR changes how reflective method invocations are done: instead of a generated stub that unpacks the parameters and then does a virtual/special/static call to invoke the actual target, now the invoke is always a function pointer call. This allows re-using the stubs for all reflective invocations with the same signature. To further increase sharing, the type check for the receiver is no longer done in the generated stub. This allows sharing of instance method invokes with different receiver classes.

For my usual Spring petclinic-jdbc benchmark, there are 1346 unique signatures for 7855 methods that are registered for reflection.

The PR also ensure that the generated graphs and the SubstrateMethodAccessor instances do not hold on to java.lang.reflect.Method objects. That removes many unnecessary Method objects from the image heap (at the cost of a little worse error message when invoking a method with wrong parameter types).

The first commit will be merged out separately by Codrut beforehand. The commit that introduces KnownAccessors is mostly a refactoring to make the vtable base offset easier available without the need to have a RuntimeConfiguration instance.

@graalvmbot graalvmbot merged commit 5307e48 into master Apr 28, 2022
@graalvmbot graalvmbot deleted the cwi/GR-38070-reflection branch April 28, 2022 06:40
@ChristophTF
Copy link

After commit 395e75b we observed a notable increase in entry points reported by -H:+PrintAnalysisCallTree.

The option considers every override of a registered virtual method as an entry point:

if (m.isVirtualRootMethod()) {
for (AnalysisMethod impl : m.getImplementations()) {
AnalysisError.guarantee(impl.isImplementationInvoked());
roots.add(impl);
}
}

Since reflection-accessible methods are now registered as roots directly,

and Object's members are made reflection-accessible by default,

RuntimeReflection.register(Object[].class.getMethods());

every derived toString() and hashCode() also appears as entry point.

For a minimal Hello World program the number of printed entry points therefore increased from ~900 to ~1500.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants