Hi Paul,
I am still trying to find the key to making indy performing better on
cold calls (and in general). Something that seems to be a real uphill
battle.
Maybe a small extract of things I concluded so far...
Reflection:
* Reflection in newer Java uses MethodHandles and is very fast
* Reflection will get us no where in the problem area of JPMS or
@CallerSensitive. That said, this is for a central invoke style
invocation like MetaClass.invoke or InvokerHelper.invoke. There might be
ways around.
* Reflection is fast for the cold path because they use only very few
LambdaForms in the end
MethodHandles:
* have a huge one-time-creation cost per lambda form, which is cached.
* adapters caused by insertArguments, folding, asType and all that
change the Lambdaform, resulting in huge one time cost.
* A simple invocation of a MethodHandle with an previously unused lambda
form results in code that performs about 10-15 times slower than doing
the same via reflection on the cold path
* important: cold path is not hot path, it has to be looked at
independently and is for the first few invocations
* @CallerSensitive and JPMS can be made working properly for this
* Reflective Methods can be unreflected to get a MethodHandle, but these
are not the high performing handles Reflection uses inside.
HiddenClasses nest mates:
* could be used to replace our current bytecode generation for callsites
* they are part of the same classloader and module, making the old
callsite mechanism more interesting for the JPMS case again.
* This will not gain performance, but may make things more "correct" and
usable for JPMS
* Still @CallerSensitive may not work properly for this. The same as
now. But for getting the caller class loader or module, this would work
better than now.
* bytecode generation (hidden class or not) is even more expensive for
the cold path
The whole thing is quite frustrating because I am basically fighting JVM
implementation details I have no influence on and that are possible
subject to change. It makes me consider to investigate Graal again.
Maybe I can get further with the help of AI here. Also I may have to
consider an change of architecture away from the callsite view to a
receiver view for the cold path. There are still a few things to
investigate. Will this influence beta-1... probably not. If I have to do
a really really big change maybe. But then I will of course start a
Thread here. I may for example change how the callsite for indy are
generated to get away from the specialized types. Maybe even a Handle
calling reflection. Promoting from cold to hot path implementation is
also not easy, since everything I add will potentially make the cold
path slower.
bye Jochen
On 7/4/26 08:57, Paul King wrote:
Hi folks,
Thanks to everyone for helping get out the last round of releases.
In Jira, I renamed the next Groovy 6 release to be 6.0.0-beta-1.
Depending on any feedback we get, we can always rename back to
alpha-3, or if we decide that we are in fact feature complete, we
could push for RC-1 instead.
There are a few open PRs and a few open GEPs we should discuss as we
lock those in for Groovy 6/7 versions. I'll send those as separate
emails over the coming week. The optimistic plan would be a beta-1 in
a few weeks, then RC-1 a few weeks after that, and then 6 GA a few
weeks after that. But obviously, more versions and/or more time
between versions if we need it.
We have also been in discussions with JetBrains about working with
them to improve the Groovy plugin for IDEA. I think that is something
we should try to do next once 6 looks locked down (which it is or is
close).
I also have draft reference implementations for groovy-ginq-sql (SQL
and jOOQ extensions for groovy-ginq) and for switch pattern matching,
but they are things I think we should target for Groovy 7. That is two
of the "seeking feedback" emails I hope to write soon but feel free to
look at the draft PRs in the meantime if you want.
Cheers, Paul.