[jmm-dev] bitwise RMW operators, specifically testAndSetBit/BTS

Doug Lea dl at cs.oswego.edu
Wed Jul 20 19:16:26 UTC 2016

Replying to Hans by replying to myself :-)

On 07/20/2016 08:49 AM, Doug Lea wrote:
> in C++-relaxed, compilers cannot perform
> some forms of  common subexpression elimination in the presence of possible
> aliasing, but for Java-plain (and C++-plain), they can.  As in:
> class Point ( int x, y; }
> void f(Point a, Point b) {
>   int r1 = a.x;
>   int r2 = b.x;
>   int r3 = a.x; // simplify to: int r3 = r1 ?
>   use (r1, r2, r3);
> }

Or, in pseudo-VarHandle style using "getM" (for varying Ms):

static VarHandle PX = MethodHandles.lookup().findVarHandle(Point.class, "x", 

void f(Point a, Point b) {
   int r1 = PX.getM(a);
   int r2 = PX.getM(b);
   int r3 = PX.getM(a); // *
   use (r1, r2, r3);

Can you simplify (*) to "r3 = r1" ? It depends on M:
* Java-Plain and C++-Plain: yes.
* Java Opaque: no.
* C++-Relaxed: only if a != b.
* (And, for the record, other modes: no)

This is one reason "opaque" mode is needed. Neither Plain nor Opaque exactly
match C++ Relaxed atomics, but together you can express everything (and
probably more).

You can create similar but more contrived-looking examples for
read-after-write and write-after-write. And also for write-after-read,
but that one may interact with out-of-thin-air and related issues.
(Which if we had a good enough solution for, or even knew how to
encapsulate, fleshing out formal/formalizable specs on the above should
not be hard. People do continue to work on this, so there is still hope.)


More information about the jmm-dev mailing list