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