final field values should be trusted as constant (filed as JDK-8233873)
Doug Lea
dl at cs.oswego.edu
Fri Nov 15 00:46:34 UTC 2019
On 11/13/19 4:23 PM, John Rose wrote:
> Also tricky is smashing of finals of normally-constructed objects, which is
> allowed by the JVM. This is allowed even if heinous. We need some
> Big Hammer to turn off optimization when it happens. If we were really
> slick we might try to amend the JMM to declare that the JIT can retain
> a previously folded value, even after somebody smashed it, on the grounds
> that this is a valid race condition, where the JITted code is racily reading
> back in time. (Is this already true??
I strongly suspect it is or could be sometimes true already, for example
when reads are hoisted out of loops. So there is not much of an argument
against the simplest interpretation of the final field rule: the first
value ever read by any thread is allowed to the only value ever used by
all threads. Although with some practical accommodations:
>
> C. Demand that frameworks which make off-label objects be upgraded
> to include a memory fence after they are done setting their finals, so
> that they conform to the JMM behaviors required of regular objects.
I think that some (all the reliable ones!) already do so. Dependency
injection frameworks (which can be worst offenders) were the main reason
for adding explicit fences to Unsafe in jdk7, prior to the current full
VarHandle (plus fence) scheme in jdk9. If frameworks don't use them,
programs are still buggy. Where "buggy" means that readers are only
guaranteed to see a typesafe value. Maybe with a a context-specific
stronger guarantee; maybe not. My sense is that even the most egregious
cases set fields before publishing to make accessible to other threads.
Otherwise even now, bad things would routinely happen when multiple
threads disagree about values.
> E. Some balanced combination of the above.
The remaining balance may be a matter of leaving a couple of loopholes:
System.setIn and a few others could be treated magically, which they
already are (but perhaps with an apologetic-sounding new annotation
@NotReallyFinal). And dealing with the dubious legality of setting a
final field more than once, with intervening reads, in a constructor.
Maybe this could be deprecated, since this case doesn't seem to have a
semantics, and would remove the weirdness that "could be final" analysis
does always not apply to finals.
-Doug
More information about the hotspot-compiler-dev
mailing list