Release store in C2 putfield
aph at redhat.com
Fri Sep 5 13:57:44 UTC 2014
On 09/05/2014 02:08 PM, Doug Lea wrote:
> I'm trying to disentangle the many interrelated issues here,
> mainly wrt to JMM and possible revisions. A few notes/comments:
> 1. As far as I can see, the G1 post barrier enforces ordering,
> but the plain one (GraphKit::write_barrier_post) does not.
> On the other hand, some GC barrier-related mechanics seem to
> be strewn elsewhere, so might have this effect. In particular,
> the release inside Parse::do_put_xxx seems suspicious.
> I'd expect CMS, but not the other GCs, to have the
> same constraints as G1. I'd also expect the ordering constraints
> to sometimes have a significant overall performance cost on ARM and
> Power. (The G1 ordering enforcement changes were apparently
> performance tested only on TSO machines; see
> and follow-ups).
> (Aside: Yet more reasons to hate card-marking.)
That G1 code isn't so bad: it is at least conditional in that the card
is read and the memory barrier is used if and only if the card is not
young. The code to which I really object uses a release store for
every card table write.
There seems to be a convention (of which I was unaware) that one
either implements acquire- and release- reads and writes or
implements barrier instructions. Both the type of the MemNode and the
explicit barriers are retained thoughout compilation, so one can use
either. I have been trying to use barriers and aquire/release as
appropriate, so I implemented both, which is why I ran into problems.
Note that there is no explicit barrier associated with the card table
release store, so the latter group of targets (which use barrier
instructions) will emit a normal store. This makes no sense to me:
either the card table needs a release or it doesn't.
> 2. Hans Boehm has argued/demonstrated over the years (see for
> example, http://hboehm.info/c++mm/no_write_fences.html), that
> StoreStore fences, as opposed to release==(StoreStore|StoreLoad)
> fences, are too delicate and anomaly-filled to expose as a
> programming mode. But there are cases where they may come into
> play, for example as the first fence of a volatile-store
> (that also requires a trailing StoreLoad), that might be
> profitable to separate if any other internal mechanics could
> then be applied to further optimize. And even if not generally
> useful, they seem to apply to the GC post_barrier case.
> 3. We are indeed strongly considering simplifying the revised
> Java Memory Model to require release fencing on construction,
> not just in the presence of final fields. In the ideal implementation,
> this would require multiple fences (i.e., more than the one
> needed anyway to force object header sanity) only if "this"
> escapes within a constructor. But because some of these fences are
> currently hard-wired and so not amenable to elision/optimization,
> carrying this out on non-TSO will probably take some effort.
That does sound sensible.
> 4. Reminder to Andrew: We cannot let the VM crash when people
> write racy/wrong code including unsafe publication.
There's absolutely no way I'd do that, and I'm rather surprised that
anyone got that idea. I emit a write barrier after object creation,
and another after an initializer with final fields.
I am arguing against every oop store being a release store, which
seems Very Wrong to me. (This seems to be for IA64, which as far as I
know is a private SAP target. This code really should be marked
IA64-ONLY, but it would be even better to reorganize the way this
stuff is handled in HotSpot.)
I am wondering whether to give up trying to use acquire and release
instructions for the time being, and fall back to using explicit
barriers. It's rather messy, but it's good enough until this gets
sorted out properly.
More information about the hotspot-dev