Simpler cmpxchg-oop?

Roman Kennke rkennke at redhat.com
Wed Aug 29 20:33:46 UTC 2018


Hi there,

as we're currently discussing cmpxchg-oop for upstream GC interface, I
wonder if we can come up with a simpler cmpxchg-oop routine.

We currently do something like this:

oop cmpxchg_oop(oop newval, oop* addr, oop cmpval) {

  oop res = cmpxchg(newval, addr, cmpval);
  while (res != cmpval && rb(res) == rb(cmpval)) { // false failure path
    cmpval = res;
    res = cmpxchg(newval, addr, cmpval);
  }
  return res;
}

We even unroll this a little bit in assembly.

However, since we're only interested in false-negatives, and because
there are limited number of states for cmpval and field-val, and because
state in fieldval can only go from fromspace -> tospace, I believe it is
enough to try at most two more times:

oop cmpxchg_oop(oop newval, oop* addr, oop cmpval) {

  oop res = cmpxchg(newval, addr, cmpval);
  if (res != cmpval && rb(res) == rb(cmpval)) { // false failure path
    // Here we can have either cmpval or res in fromspace, but not both
    // A second false-negative can only occur if another thread
    // updates the field concurrently. Any such field update can only
    // store to-space values. That means the 2nd false-negative can
    // only happen if the field was from-space and cmpval was to-space
    // in the first attempt.
    cmpval = res;
    res = cmpxchg(newval, addr, cmpval);
    if (res != cmpval && rb(res) == rb(cmpval)) { // false failure path
      // We can falsely fail a 2nd time only if field has been updated
      // to to-space, and cmpval was from-space before. At this point
      // no more false negatives can occur.
      cmpval = res;
      res = cmpxchg(newval, addr, cmpval);
    }
  }
  return res;
}

Is that right? Can somebody come up with a case where a 3rd or more
false failures can occur?

I am asking because two chained if-else branches may be simpler to
construct in C2 ideal graph (and even C1 LIR?) than a loop. And we could
drop the loop-backedge in assembly too (we already have two unrolled
retries in assembly iirc.)

Roman



More information about the shenandoah-dev mailing list