Replace MemBarRelease for final field write with MemBarStoreStore

Aleksey Shipilev aleksey.shipilev at oracle.com
Wed Sep 2 14:55:21 UTC 2015


On 09/02/2015 05:12 PM, Vitaly Davidovich wrote:
> It seems Aleksey's article is at odds with Hans' article.  Specifically,
> Hans talks about the case (which Aleksey alludes to as well):
> x.a = 42;
> x.a++;
> <store_store>
> 
> Hans mentions that x.a load can move past the store_store barrier
> despite there being a dependence (i.e. we shouldn't rely on
> dependence).  Aleksey then states the following when talking about the
> read side:
> 
>     Turns out, most hardware also respects the order of so-called
>     'dependent' reads, and hence does not require emitting the barrier
>     there.

No, Aleksey says:

"This covers for a corner case when the final field value depends on
some field (the interesting example if we do the increment of the field
itself) which experiences a racy update. This corner case may result in
storing the value derived by that racy update, not by constructor
itself, and that would obliterate the safe construction guarantees"

...which basically reiterates Hans' example.

> But Aleksey's explanation of why StoreStore isn't sufficient is 
> basically leaning on Hans' example, which in turns talks about not 
> relying on dependence. But then we rely on dependence on the read 
> side? It doesn't make sense to me.

That's because Hans' example talks how memory dependencies on *writer*
side do not enforce ordering, letting a speculative load in
"constructor" to bypass the fence, thus capturing the racy value.

"reader"-side load dependence would not save you if we are talking about
some non-related field that escapes the dependence.

This is how I understand Hans' argument, anyway:

static int G = 0;

A a;

class A {
  int x;
}

Thread 1:
 A ta = <new>
 ta.x = G;
 assert (ta.x == 0); // may fail, captured a racy update
 storeStoreFence();
 a = ta; // publish

Thread 2:

 A ta = a;
 if (ta != null) {
    G = 42; // NOT a dependent access, bummer
    assert(ta.x == 0); // may fail, value got contaminated
 }

(Hans describes the oddity of committing the store to ta.x before the
load of G is fully satisfied, read Andrew's link carefully:
http://www.hboehm.info/c++mm/no_write_fences.html)

On Wed, Sep 2, 2015 at 10:25 AM, Andrew Haley <aph at redhat.com> wrote:
> I am not convinced that the reasoning is certainly sound (or
> that it applies to HotSpot in its present form) but I believe that it
> may be and I am therefore applying the precautionary principle.

I'm with Andrew on this stuff. Sorry Hui Shi!

This seems to be far more complicated than it appears to an unexposed
person, and was discussed at lengths over and over again. I'd table the
StoreStore optimization story until after VarHandles (and possibly
storeStoreFence) arrive, and implications are more well-understood. See
e.g. the recent discussion:
 http://mail.openjdk.java.net/pipermail/jmm-dev/2015-August/000198.html

Thanks,
-Aleksey

> On Wed, Sep 2, 2015 at 9:58 AM, Andrew Haley <aph at redhat.com
> <mailto:aph at redhat.com>> wrote:
> 
>     On 09/02/2015 02:55 PM, Vitaly Davidovich wrote:
>     >     Probably not.  See http://www.hboehm.info/c++mm/no_write_fences.html
>     >     for an explanation.
>     >
>     > Is that really relevant to final/stable field writes though?
> 
>     I believe so.  See also
>     http://shipilev.net/blog/2014/all-fields-are-final/,
>     "Implementation Support"
> 
>     Andrew.
> 
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20150902/cc4de0d1/signature.asc>


More information about the hotspot-compiler-dev mailing list