New draft JEP: intrinsics for String::format and Objects::hash (among others)
brian.goetz at oracle.com
Mon Oct 22 21:30:24 UTC 2018
> I've recently discovered that the latest version of Eclipse is using Objects.hash() by default when you ask to auto-generate the hashCode,
> obviously this is plainly wrong because the current implementation does a lot object allocations, but at the same time, the code is more readable.
> So +200 on this JEP !
Well, it's right, but it may have a surprising(ly bad) cost model. The
goal here is to let people write the right code, with the right
(awesomely good!) cost model. (And same for toString using
String.format()). These two methods were picked as first targets
because (a) there is a significant win to be had for both, and (b) every
class should use them.
> Now, the issues i see.
> if you translate the bytecode, you are loosing the call to String.format() so if there is a NPE because one of the parameter is null, String.format() will disappear from the stacktrace of this NPE.
Yes, correct. The stack trace will point back at the line calling
> Also, from the point of view of the bytecode analyzers that do an abstract execution of the bytecode (Jacoco, Findbugs, Proguard, any IDEs, etc) each of them will have to have a mechanism to go from the invokedynamic call to the original call so it an be interpreted. It's seem to be a waste of resources to not a standard way to get the original call at bytecode level.
This is a general issue with any sort of indy code generation from
javac; bytecode interpreters may want to learn the meanings of standard
bootstraps, considering them to be "new bytecodes". The same will be
true when we start generating indy for switch translation, or switching
to condy for lambda translation, or starting doing more aggressive
Note that while we're waiting for full constant folding, intrinsics can
do limited constant folding too, such as
> Limiting these intrinsics to the JDK methods has a big drawbacks, it makes the performance model less easier to understand.
> By example, String.valueOf() will be fast but the method debug(String format, Object...) of a LOG4J Logger will be slower (even if it changes its implementation to use String.format internally because the format parameter will not be constant inside the implementation).
This is really two separate issues. The real concern you're raising
here is that by intrinsifying some methods, sometimes, but not others,
and not at other times, the cost model becomes less transparent. This
is true, but this is also a fact of life with dynamic compilation, JVM
intrinsics, etc. Glass p% empty / q% full.
> I understand that you do not want to open the pandora box of offering a macro system to everybody, but i hope there is a knd of middle ground, here, perhaps by enabling any methods to use the instrinsics annotation but to limit the bootstrap methods that can be used to the ones defined in the JDK.
Yes, we may eventually consider loosening up along some axes, once we
have a better understanding of the risks, costs, and benefits. For now,
restricting it to the JDK is a no-brainer, while we gather data on
efficacy and use cases. There are many other potential targets in the
Intrinsification might not result in an indy; it might result in an LDC
(condy or not), or it might result in a shuffling of the parameters and
a redirection to another method (yes, both can be simulated by indy, but
at a cost.) So "restricting bootstraps" is not an effective axis of
restriction, but we can continue to look for axes along which this might
be reasonably expanded.
More information about the amber-spec-experts