for review: 8236522: "always atomic" modifier for inline classes to enforce atomicity

forax at univ-mlv.fr forax at univ-mlv.fr
Sat Mar 7 22:22:05 UTC 2020


----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Samedi 7 Mars 2020 22:52:12
> Objet: Re: for review: 8236522: "always atomic" modifier for inline classes to enforce atomicity

> On Mar 7, 2020, at 1:41 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>> 
>> [Moving to valhalla-spec-experts]
>> 
>> ----- Mail original -----
>>> De: "John Rose" <john.r.rose at oracle.com>
>>> À: "Tobias Hartmann" <tobias.hartmann at oracle.com>
>>> Cc: "valhalla-dev" <valhalla-dev at openjdk.java.net>
>>> Envoyé: Vendredi 21 Février 2020 11:23:14
>>> Objet: Re: for review: 8236522: "always atomic" modifier for inline classes to
>>> enforce atomicity
>> 
>>> I’ve come back around to this feature, after (SMH) realizing
>>> it should be a marker interface (java.lang.NonTearable) instead
>>> of a new modifier and access flag.  Thanks, Brian…
>> 
>> In my opinion, using an annotation here cross the rubicon,
>> user available annotations are not supposed to change the semantics of a
>> language construct, they are metadata.
> 
> I agree.
> 
>> Do you really want the memory model to make reference of an annotation ?
> 
> No.
> 
>> Or worst, do you think that you can avoid to change the JMM to describe the
>> effects of always atomic inline classes ?
> 
> The JMM has to change, but it doesn’t have to mention any Java syntax.
> I’m anticipating that we adjust the existing language about tearing of
> longs and doubles to cover values also.
> 
>> What is the reason to change/move the line here ?
>> Are you envisioning other annotations that can change the semantics ?
>> 
>> Why can not be a keyword at source level and an attribute at classfile level ?
> 
> 
> So, that’s a different question.  It shouldn’t be that either, IMO, because
> that is also disruptive to the specifications.  Keywords and attributes
> cost a lot to specify and implement, right?

yes, but cutting corners inflates the bill of later releases.
A cost that you know may be better than a cost that is hard to evaluate.

> I prototyped a keyword, and backed away to a marker interface, which I think is the right answer.

Marker interface are usually problematic because:
- they can inherited, for inline classes, you can put them on our new kind of abstract class, which will make things just harder to diagnose.
- they can be uses as a type, like Serializable is used where it should not.
  By example, what an array of java.lang.NonTearable means exactly. There is a potential for a lot of confusion. 

and in the specific case of NonTerable, a non inline class can implement it, again creating confusion.

> 
> So: not an annotation, not a keyword, but a marker interface.
> It is certainly the path of least resistance for a prototype, so we’re
> doing that right now.  It might even be the right answer in the long
> run.  Here’s the current draft java doc for java.lang.NonTearable:

If it's for a prototype, i see no problem apart the name, the name should start with underscores to make it clears that this is a temporary construct.

> 
>> 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.
>> 
>> <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.

that the problem of choosing a mecanism, an interface, that can be inherited.

> 
> Comments?
> 
> — John

Rémi


More information about the valhalla-spec-experts mailing list