On 23.06.2016 15:57, Wilson MacGyver wrote:
I think what Jochen means is, Indy requires jdk 7. Once 9 comes out, it
will be safe to drop Jdk 6 support.
Thus no need for non Indy version
basing only on indy means no JDK 6 support anymore, that is very right.
But there are actually a couple of possible reasons... but let me give
some basic background...
We have basically 3 ways for method invocations in the Groovy runtime:
Reflection, MethodHandles (used by indy) and runtime generated classes.
The non-indy version uses reflection for the first call, to then
generate an accessor method and use that in later calls. We do this for
speed reasons, as we then get quite near the speed of a normal method
call plus a bit overhead, that cannot be really avoided. Reflection used
to be quite slow, but got a lot faster. It is possible that hotspot
could now optimize away most of the overhead of Reflection compared to a
normal method call and that this means we actually have no need anymore
to use our runtime generated classes. That is something to test.
If we keep the runtime generated classes we have these problems in JDK9:
(1) jigsaw imposes new access restrictions on classes, that get in the
way. It is not yet clear to me if that really restricts our callsite
caching. Reflection and MethodHandles (used by indy) are less
restricted, thus I can make more cases work. At the very least the code
will have to know about the module system and react to it. This would
require us making dynamic named modules and layers, but generating those
and what they will actually be able to do is still largely unspecified
in jigsaw it seems, so I am kind of blocked here for now. The effects
here also depend on if Groovy itself will become a module or not.
Possible effect: works in less cases, more fallback to reflection and
possibly reduced performance
(2) the class sun.reflect.MethodAccessorImpl, which we use for our
callsite caching to generate accessor methods is now internal API
protected by the module system and thus no longer available. If that
class is not available, we fall back to pure reflection based logic. We
can change to not use this any more, but it means our runtime generated
classes will be verified, and that means it will take longer to generate
the cache. The impact of this can be so big, that it will not be worth
producing that class anymore. Possible effect: reduced performance
Reflection and MethodHandles produce classes at runtime too, but those
come from the internals of the JDK and have extended access rights
compared to those we could generate. Part of the reason why Reflection
performs not as good is the requirement to check access rights to a
method on each method invocation done with reflection. MethodHandles on
the other hand, have a single check during the creation of the handle,
thus do not require the overhead of reflection to that extend. So
another possible solution could be to replace the usage of reflection
with MethodHandles and most likely skip generating the runtime generated
classes as well. The nice effect of this would be, that the
implementations of the old callsite caching and the indy version would
become almost identical, removing a lot of classes.
The most likely outcome though seems to be for me to keep the old way
for pre JDK9 and to do something MethodHandles based on JDK9 itself,
maybe already for JDK8.
Dropping JDK6 support would in theory allow us to completely remove the
old way, but I do not trust JDK7 here. The implementation of the
MethodHandles in JDK7 has been very buggy for a long time, up to the
point that I cannot advice using invokedynamic on JDK7 at all. Maybe it
is good enough in the latest JDK7 versions, but I had not yet the time
to really test the updates of 71+, before I certainly had my troubles.
And given that the last public release is update 80 from April 2014, I
really have my doubts that all the good stuff from JDK8 had a chance to
get into the right version in JDK7. Completely removing the old way thus
for me means dropping support for JDK7 as well.
bye Jochen