[jmm-dev] ECOOP, JVMLS

Doug Lea dl at cs.oswego.edu
Wed Aug 6 16:04:06 UTC 2014

On 08/05/2014 01:56 PM, Hans Boehm wrote:
> I'm still apprehensive about relaxing the final field rules.  I'll withhold
> judgment until I see what we actually come up with.

For the sake of your main concerns, I think it suffices to just assume
it takes the form of a guaranteed C++/C11 memory_order_release
fence upon constructor exit.

> The core question here, which everyone seems to gloss over, is what we
> guarantees we provide on the reader side.  I think the current plan is to
> guarantee only reference-load-to-field-load-ordering, and no other ordering
> guarantees based on dependencies.


>   But I think it only eliminates a proper subset
> of the surprises that we are worried about.  If field i is only set in x's
> publication-safe constructor, which also sets the corresponding entry in
> static array a, a[x.i] may still see an uninitialized a entry because the
> read from x and the read from a are not ordered.  (As indeed they might not
> be in practice if a is known to contain only a single element.)

Aside: It is always hard to define the scope of surprisingness.
We'd be much better off if we could base decisions off
programmer error rates, but we don't have enough data to do this.
Short of this, pretty much all we can say is that people who only
want to be surprised by non-SC-ness should only use locks and then
check for surprises by checking if they used them everywhere applicable.

Here, I'm not sure who would be surprised that if a constructor
accesses non-local state, then without care, there are few/weak
reader-side guarantees.

> It was the reader-side constraints that would have slowed down a DEC alpha
> implementation.  Although Alpha doesn't matter any more, that's still where
> the issues are.
> The down side is that such a change seems to sanction this kind of racy
> programming, while leaving plenty of traps like the array example above.
>   Paul, Torvald et al, have spent some time looking at this in the context
> of RCU in the Linux kernel, and ordering for field references doesn't seem
> to cover nearly all the cases that people actually expect to work.  It

Paul: Can you summarize?


> seems to me that we're really trading a moderately subtle trap for more
> subtle ones that maybe occur less than half as often, possibly also with
> some loss in race detector precision.  Maybe that's a win, but I can't get
> excited about it.  I would be more positive about it if we add sufficient
> annotations to at least negate any race detection impact.
> This is all closely related to the memory_order_consume stuff on the C++
> side.  That seemed like a good idea at the time, in spite of the fact that
> it greatly complicated the memory model (as do the current final field
> semantics).  But so far that has not worked out well in practice; nobody
> really implements it.  And it doesn't seem to be really useful, perhaps
> because we went too far in generalizing what we allow on the reader side.
> Hans
> On Tue, Aug 5, 2014 at 7:01 AM, Doug Lea <dl at cs.oswego.edu> wrote:
>> On 08/05/2014 03:17 AM, John Rose wrote:
>>> On Aug 3, 2014, at 5:36 AM, Doug Lea <dl at cs.oswego.edu
>>> <mailto:dl at cs.oswego.edu>> wrote:
>>>   * Everyone seems to strongly favor the idea of replacing final-field
>>>> specs with those that amount to guaranteeing release fences in
>>>> constructors.  Still lots of details (some depending on core model) to
>>>> work out though.
>>> This change makes it easier to define interesting variations on final
>>> variables.
>> Yes, many increasingly common variants.
>> Aside: Here's some reconstructed history about this.  (Hans and
>> Jeremy, feel free to correct.) At one point in JSR133, some of us
>> proposed something along the lines of release-on-construct. The DEC
>> Alpha folks strenuously objected and showed that it would cause a big
>> (I vaguely recall 6X) performance hit in their (now long gone) JVM.
>> And they further argued that use cases relying on it were buggy anyway
>> because they lacked locks on read side that would be needed possibly
>> even for final fields in some then-planned Alpha processors.  So we
>> (mainly Jeremy and Bill) pursued the clever but complicated
>> freeze/final approach to only cover the minimal required case,
>> explicitly final fields. We might have done otherwise had we noticed
>> at the time that:
>> * JVMs rely (at least sometimes) on sanely released object headers
>> anyway.  While it might not be logically impossible to do otherwise,
>> it would either severely limit efficiency of internal GC etc
>> algorithms or require unknown techniques. (Getting internal release
>> mechanics under new rules to coincide with those for initializing
>> assignments (in the absence of leakage etc) might require some JVM
>> implementation work, but nothing that seems very challenging.)
>> * Even though most programmers don't consciously say so, most
>> intuitively believe that construction implies release.  They make more
>> errors when their intuitions are wrong, especially when they try to
>> implement various monotonic, semi-final idioms that are otherwise fine
>> but inexpressible.  Changing rules does open up the moral hazard that
>> people will overgeneralize to cover more cases than they do, but
>> that's not a very good argument for keeping current rules.
>> -Doug

More information about the jmm-dev mailing list