Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits in "Hash Codes and Object Header Interference" section.

...

If we have a race between a T-deflate thread and a thread trying to get/set a hash code (T-hash), then the first race is between the
ObjectMonitorHandle.save_om_ptr(obj, mark) call in T-hash and deflation protocol in T-deflate. Note: ref_count is not mentioned in any of the previous sections for simplicity.

Start of the Race

    T-hash                  ObjectMonitor              T-deflate
    ----------------------  +-----------------------+  --------------------------------------
    save_om_ptr() {         | owner=NULL            |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
      :                     | count=0               |
      atomic inc ref_count  | ref_count=0           |
                            +-----------------------+

...

    • T-deflate has set the owner field to DEFLATER_MARKER.
    • T-deflate is about to check the waiters and ref_count fields.
    • T-hash is about to inc the ref_count field.

T-deflate Wins

If T-deflate wins the race, then T-hash will have to retry until the object and/or ObjectMonitor are stable.

    T-hash                    ObjectMonitor              T-deflate
    ------------------------  +-----------------------+  --------------------------------------
    save_om_ptr() {           | owner=DEFLATER_MARKER |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
      atomic inc ref_count    | count=-max_jint       |  if (waiters != 0 or ref_count != 0) {
      if (owner ==            | ref_count=1           |  }
          DEFLATER_MARKER) {  +-----------------------+  prev = cmpxchg(-max_jint, &count, 0)
        atomic dec ref_count             ||              if (prev == 0 &&
        return false to                  \/                  owner == DEFLATER_MARKER) {
          cause a retry       +-----------------------+    restore object header
      }                       | owner=DEFLATER_MARKER |    finish the deflation
                              | count=-max_jint       |  }
| ref_count=0 |
+-----------------------+

...

If T-hash wins the race, then the ref_count will cause T-deflate to bail out on deflating the monitor which is what this diagram shows; ref_count is . Note: header is not mentioned in any of the previous examples sections for simplicity.

    T-hash                    ObjectMonitor              T-deflate
    ------------------------  +-----------------------+  ----------------------------------------
    save_om_ptr() {           | header=dmw_no_hash |  cmpxchg(DEFLATER_MARKER, &owner, NULL)
      atomic inc ref_count    | owner=DEFLATER_MARKER |  if (waiters != 0 or ref_count != 0) {
      if (owner ==            | count=0            |    cmpxchg(NULL, &owner, DEFLATER_MARKER)
          DEFLATER_MARKER) {  | ref_count=1 |    bailout on deflation
      }                       +-----------------------+  }
      if (object no longer               ||              prev = cmpxchg(-max_jint, &count, 0)
          has a monitor or \/
          is a different +-----------------------+
          monitor) { | header=dmw_no_hash |
        atomic dec ref_count | owner=NULL |
        return false to | count=0 |
          cause a retry | ref_count=1 |
      } +-----------------------+
      save om_ptr in the ||
        ObjectMonitorHandle \/
    } +-----------------------+
if save_om_ptr() { | header=dmw_hash |
if no hash | owner=NULL |
gen hash & merge | count=0 |
hash = hash(header) | ref_count=1 |
} +-----------------------+
atomic dec ref_count
return hash

...