[jmm-dev] ECOOP, JVMLS

Hans Boehm boehm at acm.org
Tue Aug 5 17:56:16 UTC 2014

I'm still apprehensive about relaxing the final field rules.  I'll withhold
judgment until I see what we actually come up with.

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.  In C++ terms, every load is implicitly a
memory_order_consume load, but the enforced dependencies are restricted to
field loads, as they are now for final fields.  That avoids substantial
additional complications.  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.)

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
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.


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