RFR: JDK-8207169: X86: Modularize cmpxchg-oop assembler for C1 and C2

Roman Kennke rkennke at redhat.com
Wed Aug 29 14:13:49 UTC 2018


It was suggested to me (off-list) to simply put this stuff under if
(UseShenandoahGC). I don't have a very strong preference about this. I'm
leaning towards having a (somewhat) proper GC interface for it, if only
because of the symmetry with the runtime GC interface that also has a
cmpxchg hook, and because, cmpxchg(-oop) is, in-fact, a heap-access and
should thus go through the GC interface.

So, how do others feel about this? Better to put this under
Shenandoah-specific paths? Make it a proper GC/BarrierSet-interface? I
also very much welcome suggestions for improving the suggested interface.

Please let me know.

Roman

> I am x-posting hotspot-compiler-dev and hotspot-gc-dev because it
> touches both areas.
> 
> Currently, cmpxchg-oop is generated a single instructions plus probably
> some oops-compression. Shenandoah GC (and most likely other concurrent
> compacting GCs) needs to generate some more code to deal with possible
> false-negatives when comparing old-value with the field contents.
> 
> The way we solve it in Shenandoah is to basically retry (with resolved
> expected-value) on the failed-path of the CAS. Another solution (I
> believe ZGC does that) is to punch the resolved value into the field
> (using a CAS) before doing the actual CAS.
> 
> 
> We want to do this in assembly because:
> 1. it is very cumbersome and error-prone to construct the LIR and ideal
> graph for the retry-loop.
> 2. the assembly can be reused for both C1 and C2
> 3. the generated code is pretty much the same
> 
> This change includes both C1 and C2 changes, and it should probably be
> broken up, but I wanted to present the whole picture first, so that we
> can discuss the solution with all aspects.
> 
> Some notes:
> 
> - The BarrierSetAssembler::cmpxchg_oop*() paths are only used when
> BSA::handle_cmpxchg_oop() returns true. This is done because the
> (Shenandoah version) BSA::cmpxchg_oop() requires 2 tmp registers, and we
> don't want to penalize GCs that don't need this by allocating 2
> registers that are subsequently not used.
> - I added a diagnostic flag BarrierSetAlwaysHandlesCmpxchg to be able to
> exercise the BSA::cmpxchg_oop() path even for other GCs, e.g. for
> testing purposes. We can remove that if it's too much hassle.
> - I want to be able to distinguish the case where expected-value is
> known to be NULL, because in this case we don't need the extra handling
> of cmpxchg_oop() and can use plain CAS.
> - I want to distinguish entries for c1 and c2 into BSA because we are
> doing some extra fluff for C1 (namely, resolving the cmpval because we
> cannot easily do this in LIR)
> - the compressing of uncompressed oops is moved into the C1 version of
> BSA::cmpxchg_oop()
> 
> Bug:
> https://bugs.openjdk.java.net/browse/JDK-8207169
> Webrev:
> http://cr.openjdk.java.net/~rkennke/JDK-8207169/webrev.00/
> 
> What do you think? Can I get reviews?
> 
> Thank you!
> Roman
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20180829/4dad4db0/signature.asc>


More information about the hotspot-gc-dev mailing list