[jmm-dev] The JSR-133 Cookbook and final fields

Hans Boehm boehm at acm.org
Sun Nov 20 23:40:21 UTC 2016


Java optimizers are not generally allowed to reread a globally visible
field when the original code didn't. This is yet another reason for that
restriction.

This is different from C and C++.

On Sun, Nov 20, 2016 at 1:37 PM, Petr Chalupa <email at pitr.ch> wrote:

> Thanks, I did not realise this is actually ill-advised. The read of b is
> racy so it should be no surprise that the value based on it in the final
> field can differ.
>
> However I've remembered http://www.hboehm.info/c++mm/why_undef.html and
> got
> a thought how to change the example to be maybe problematic again:
>
> In the constructor with a body as follows
>
> final T a;
> T b;
>
> X() {
>     T local = computeAValue();
>     b = local;
>     doMoreOtherThings();
>     // b never modified, it is equal to local
>     a = local; // line A
> }
>
> could a compiler decide to optimise line A to a read of the same value from
> b (introducing the racy read) instead of local variable to save space? What
> am I missing, what prevents compiler to do optimisation like that?
>
> Best regards,
> Petr Chalupa
>
> On Fri, Nov 18, 2016 at 1:12 AM, Doug Lea <dl at cs.oswego.edu> wrote:
>
> > On 11/17/2016 06:41 PM, Petr Chalupa wrote:
> >
> >> Hello,
> >>
> >> If there is only StoreStore barrier at the end of a constructor then
> >> following code concerns me:
> >>
> >
> > There are several ill-advised things people can do in constructors that
> > cause the base final field guarantee to be useless. Most famously,
> > publishing "this" before assigning the field.
> >
> > static C global;
> > class C {
> >   final int a;
> >   C (int a) { global = this; this.a = a; }
> > }
> >
> > And as your example shows, initializing a final with the result of
> > a computation reading a non-final field is also a bad idea.
> > There are probably others too, all of which one hopes any concurrent
> > programmer can see are too crazy to do. (And which good tools would
> > help point out.)
> >
> > -Doug
> >
> >
> >> // Thread 1:
> >>
> >> class X {
> >>       static X instance;
> >>       final int a;
> >>       int b;
> >>
> >>       X() {
> >>           a = 0;
> >>           a++;
> >>           b = 10
> >>           a += b; // could read 42?
> >>       }
> >> }
> >>
> >> void publish() {
> >>     X.instance = new X();
> >> }
> >>
> >> // Thread 2:
> >> X.instance.b = 42;
> >>
> >> Could the read of b in constructor see 42? If it can, a StoreLoad might
> >> be required as well.
> >> Could you confirm or explain where my thought was wrong. Thanks.
> >>
> >> Best regards,
> >> Petr Chalupa
> >>
> >> On Wed, Nov 16, 2016 at 1:56 PM, Doug Lea <dl at cs.oswego.edu
> >> <mailto:dl at cs.oswego.edu>> wrote:
> >>
> >>     On 11/15/2016 01:44 PM, Hans Boehm wrote:
> >>
> >>         Generalizing final field memory ordering to non-final fields
> >>         also has
> >>         optimization consequences on the reader side that we're still
> >>         struggling
> >>         with for C++.
> >>
> >>         For example, on any flavor of ARM or Power, in
> >>
> >>         tmp = x;
> >>         ...
> >>         tmp2 = y;
> >>         if (tmp == tmp2) {
> >>             tmp3 = tmp2.a;
> >>         }
> >>
> >>         the last assignment can no longer be replaced by tmp3 = tmp.a,
> >>         because that
> >>         wouldn't preserve ordering between the load of y and that of a.
> >>         (I suspect
> >>         that such a replacement can be beneficial if the branch can be
> >>         correctly
> >>         predicted, since tmp may be available earlier.)
> >>
> >>         Presumably similar rules already apply to final field
> >> optimization.
> >>
> >>
> >>     If Tmp.a is final, both the tmp and tmp2 reads are possible only
> >>     after tmp.a is (finally) set, so the optimization is OK.
> >>     (This requires that there be no address speculation for "new"
> objects.
> >>     Otherwise all sorts of Java security properties would be broken.)
> >>
> >>     -Doug
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >
>


More information about the jmm-dev mailing list