[jmm-dev] The JSR-133 Cookbook and final fields
Hans Boehm
boehm at acm.org
Sun Nov 20 23:36:54 UTC 2016
On Wed, Nov 16, 2016 at 4:56 AM, Doug Lea <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.)
>
> Is that correct?
Consider the case in which x is written before the constructor setting a
finishes, i.e. before the freeze action/fence, and y is set after the
constructor finishes. I don't see how the transformation ensures that (in
the absence of a null pointer exception) the read of a still sees the
initialized value. (Recall that there is no longer an address dependency
from the load of y to the load of a after the transformation, though there
was before.) But it looks to me like 17.5.1 says that the read of a should
see the initialized value, though I'm not positive about my reading. And I
have a vague recollection that Jeremy's original proposal may have allowed
the read of a to see zero at this point?
Hans
More information about the jmm-dev
mailing list