Jason,
I wouldn't consider @Stable as a scalpel :-)
It's heavily locked down for a reason: it wasn't designed for eventual
standardization, but as (1) an experiment in _multiple_ directions; and
(2) solution for immediate problems in java.lang.invoke.
@Stable mixes (incomplete implementations of) 2 independent features
(lazy initialization of finals + constant arrays), while trusting
instance finals is just a consequence of locking it down to privileged
code (JIT-compilers already trust final instance fields in different
core packages).
Current implementation doesn't enforce at runtime the contract and
allows multiple writes to @Stable field. It is useful in rare cases, but
overall significantly complicates proper usage of @Stable.
All those factors make @Stable unfit for public exposure in it's current
form.
Both referenced features are independently explored (as lazy finals and
frozen arrays).
Also, @Stable is not a substitute for final fields: default value is
treated specially (not optimized), while "final" covers the whole range
of values of a type.
For optimizing final fields there are much more promising approaches:
(1) optimistic optimizations in JITs: treat finals as constants and
track updates invalidating code which relies on that (there were some
experiments, e.g. [1]);
(2) forbid final field updates at runtime after initialization is
over and freely optimize them in JITs.
Both approaches still have some roadblocks on their way (deserialization
relies on modifying final fields, hard to track final field values of
individual objects in JVM, etc), but the platform steadily moves in the
direction of treating final fields as truly final by default.
Best regards,
Vladimir Ivanov
[1]
http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2015-June/018342.html
On 1/12/18 7:33 AM, Jason Greene wrote:
MethodHandle.invokeExact() can match the performance of direct invocation, but
it requires constant folding to do so. Otherwise results are similar to Java
reflection(e.g [1]).
While TrustFinalNonStaticFields can be used, it’s a sledgehammer where a
scalpel is really be more appropriate.
The internal @Stable facility provides the desired semantics and precision, but
it is heavily locked down, with privileged code checks and export restrictions.
Could this be made more accessible (or perhaps a variant restricted to just
final fields)? Informing the compiler that a final field is a true lazy
initialized constant, with no store-to-final seems a pretty useful construct in
general. I can understand that the long term desire is that this shouldn’t be
necessary, and should be inferred [3], but at that point the annotation is
still useful as documentation and legacy compatibility. If nothing else could
it be allowed in non-privileged code via some flag?
It seems odd that the much more aggressive facility (TrustFinalNonStaticFields)
is simpler to use than a more targeted one.
Thanks!
[1] https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html
[2]
http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java
[3] https://bugs.openjdk.java.net/browse/JDK-8058164