What if...

...fields of inline classes would not be implicitly final by default. They would just not allow assignment outside constructor and they would force exactly-once assignment in constructor. This would just be a rule for final classes. Now explicit final modifier could then be used for JMM effects. For example, in this inline class:

inline class Point {
    final long x, y;
}

...there would be no tearing possible.

WDYT?

Regards, Peter

On 3/14/20 12:01 PM, Peter Levart wrote:
Hi,

Comments inline...

On 3/7/20 10:52 PM, John Rose wrote:
  Here’s the current draft java doc for java.lang.NonTearable:

An inline class implements the {@code NonTearable} interface to
request that the JVM take extra care to avoid structure tearing
when loading or storing any value of the class to a field or array
element.  Normally, only fields declared {@code volatile} are
protected against structure tearing, but a class that implements
this marker interface will never have its values torn, even when
they are stored in array elements or in non-{@code volatile}
fields, and even when multiple threads perform racing writes.

What about final fields? In current JMM they imply there is a happens before between end of constructor (where they are written to) and any read of them even after racy publication of an instance. So in effect final fields (in non-inline classes) behave as though they are written to only once (there's no pre-initialization write that would be visible). So I would expect no tearing to be visible too.

Am I right to assume that an inline type whose value is assigned to a final field of non-inline type need not be declared NonTearable ?

If I'm right, then final modifier on a field could be used to declare inline classes that don't allow tearing.

All fields of inline classes are implicitly final. But does that implicitness extends to non-tearability too? For example:

inline class Tearable {
    long x, y;
}

inline class TearableOrNot {
    Tearable t;
}

The 't' field is implicitly final. So does TearableOrNot allow tearing the t.x and t.y apart or not? If it doesn't then perhaps this could be a way to express non-tearability of inline types. Another option would be that fields of inline types are implicitly final but that only means they can't be assigned to twice in constructor or even once outside of constructor - it doesn't extend to non-tearability. For non-tearability they would have to be explicitly declared as final. But that would be confusing I think. It is already a little confusing, because in non-inline classes, declaring all fields final means that no tearing is possible. Not so in inline class where all fields are implicitly final already. But that distinction on the 1st level could be learned to live with.

Regards, Peter

<p> An inline instance of multiple components is said to be "torn"
when two racing threads compete to write those components, and one
thread writes some components while another thread writes other
components, so a subsequent observer will read a hybrid composed,
as if "out of thin air", of field values from both racing writes.
Tearing can also occur when the effects of two non-racing writes
are observed by a racing read.  In general, structure tearing
requires a read and two writes (initialization counting as a write)
of a multi-component value, with a race between any two of the
accesses.  The effect can also be described as if the Java memory
model break up inline instance reads and writes into reads and
writes of their various fields, as it does with longs and doubles
(JLS 17.7).

<p> In extreme cases, the hybrid observed after structure tearing
might be a value which is impossible to construct by normal means.
If data integrity or security depends on proper construction,
the class should be declared as implementing {@code NonTearable}.
Also, we could add a paragraph giving full disclosure about the
meaninglessness of having non-inlines implement NonTearable,
or maybe in the end we can position NonTearable in a
place where non-inlines cannot implement it.  I’m inclined to
leave it out for now, at least until we figure out the shape of the
type hierarchy immediately under Object.

Comments?


Reply via email to