User model stacking: current status
Brian Goetz
brian.goetz at oracle.com
Thu May 5 22:03:26 UTC 2022
>> Let's write this out more explicitly. Suppose that T1 writes a non-null value (d, t, true), and T2 writes null as (0, 0, false). Then it would be possible to observe (0, 0, true), which means that we would be conceivably exposing the zero value to the user, even though a B2 class might want to hide its zero.
<brainstorming>
The OOTA guarantee we get is: threads that read a variable (fields and
array elements) will only see a value that has been put there by a
"prior" write in some thread. And every variable is treated as if it
has an initial write of the default value for that variable, as per JLS
17.4.4:
> The write of the default value (zero, false, or null) to each variable
> synchronizes-with the first action in every thread.
Ignoring fields that are themselves composite values for a moment, this
means that, if we treat nulls as a full-width all-zeroes value, then
when we write a null to our DateTime example, we are _returning_ date
and time to a value that has already been written there. So reading 0
for date or time is not OOTA, though might be surprising. And writing
all the fields seems simpler and more uniform, and avoids the GC issue,
right?
So one of the other consequences of a non-atomic B2 is that not only
will races result in a torn value, but they may also expose the zero
value (or torn parts of it.) This doesn't seem entirely out of hand for
something that explicitly permits tearing.
I tried to sketch what a JLS section on "non-atomic values" might look
like, by cribbing liberally from JLS 17.7:
> For the purposes of the Java programming language memory model, a
> single write to, or read of, a variable whose type is a non-atomic
> value class or value-based class may be treated as separate writes or
> reads of its fields. This can result in a situation where a thread
> sees some field values from one write, and some field values from
> another write.
This is a start. (Plus the business about volatile.) It basically
says that from a JMM perspective, a non-volatile variable whose type is
a non-atomic value class is really a tuple of its fields. In correctly
synchronized programs, this should not be observable.
It may be the case that we can exempt _final_ variables whose type is a
non-atomic value class.
The section on final field guarantees will need heavier work (because a
final field can be nested many levels deep).
</brainstorming>
More information about the valhalla-spec-experts
mailing list