- Loading...
...
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.
T-hash ObjectMonitor T-deflate
---------------------- +-----------------------+ --------------------------------------
save_om_ptr() { | owner=NULL | cmpxchg(DEFLATER_MARKER, &owner, NULL)
: | count=0 |
atomic inc ref_count | ref_count=0 |
+-----------------------+
...
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
...