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

Doug Lea dl at cs.oswego.edu
Fri Nov 18 00:12:22 UTC 2016


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