groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: Is it possible to enable CompileStatic for an entire project
Date Thu, 23 Jun 2016 23:42:37 GMT
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

Mime
View raw message