[jmm-dev] ECOOP, JVMLS
jeremymanson at google.com
Wed Aug 6 16:56:05 UTC 2014
I've probably made my feelings on this subject known enough times, but to
- I think it is worthwhile to provide the additional guarantees, as long as
we are confident that the construction and reader side won't get too
- Otherwise, I think we should lay off.
- I'm not too worried about additional guarantees encouraging bad code
idioms. Really, 10 years later, we've done a fair bit of outreach on this
topic, and seen what we can encourage and discourage. And people are still
doing this, and still getting errors (this is similar to the argument for
tighter finalization rules).
- Aleksey pointed out to me that he had experienced bug triage where people
removed a final field from their class and started to see memory
consistency errors. Even though the guarantees currently only apply to
individual final fields, the implementation piggybacks guarantees for
non-final fields, too. It's much simpler to provide the guarantees
It's a shame we only have anecdotes. If someone can suggest a relatively
easy experiment to run, I have plenty of guinea pigs.
On Tue, Aug 5, 2014 at 10:56 AM, Hans Boehm <boehm at acm.org> wrote:
> 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