- Loading...
...
ObjectMonitor::install_displaced_markword_in_object() is called from two places so we can have a race between a T-enter thread and a T-deflate thread:
T-enter enter object T-deflate
------------------------------------------- +-------------+ --------------------------------------------
dmw = header() install_displaced_markword_in_object() { | mark=om_ptr | install_displaced_markword_in_object() {
dmw = header()
if (!dmw->is_marked() && +-------------+ dmw = header()
if (!dmw->is_marked() &&
if (!dmw->is_marked() &&
dmw->hash() == 0) { dmw->hash() == 0) {
create marked_dmw dmw create marked_dmw
dmw = cmpxchg(marked_dmw, &header, dmw) dmw = cmpxchg(marked_dmw, &header, dmw)
} } }
...
T-enter object T-deflate
------------------------------------------- +-------------+ -------------------------------------------
dmw = header() install_displaced_markword_in_object() { | mark=om_ptr | install_displaced_markword_in_object() {
dmw = header()
if (!dmw->is_marked() && +-------------+ dmw = header()
if (!dmw->is_marked() &&
dmw->hash() == 0) { dmw->hash() == 0) {
create marked_dmw create marked_dmw
dmw = cmpxchg(marked_dmw, &header, dmw) dmw = cmpxchg(marked_dmw, &header, dmw)
} }
// dmw == marked_dmw here // dmw == original dmw here
if ( if (!dmw->is_marked()) if (dmw->is_marked())
unmark dmw unmark dmw
obj = object() obj = object()
&&
dmw->hash() == 0) { dmw->hash() == 0) {
create marked_dmw create marked_dmw
dmw = cmpxchg(marked_dmw, &header, dmw) dmw = cmpxchg(marked_dmw, &header, dmw)
} }
// dmw == marked_dmw here // dmw == original dmw here
if (dmw->is_marked()) if (dmw->is_marked())
unmark dmw unmark dmw
obj = object() obj = object()
obj->cas_set_mark(dmw, this) obj->cas_set_mark(dmw, this)
...
T-enter object T-deflate
------------------------------------------- +-------------+ -------------------------------------------
install_displaced_markword_in_object() { | mark=om_ptr | install_displaced_markword_in_object() {
dmw = header() +-------------------
+ dmw = header()
| mark=om_ptr | dmw = header()
if (!dmw->is_marked() && +-------------+ if (!dmw->is_marked() &&
dmw->hash() == 0) { dmw->hash() == 0) {
create marked_dmw dmw create marked_dmw
dmw = cmpxchg(marked_dmw, &header, dmw) dmw = cmpxchg(marked_dmw, &header, dmw)
} } }
// dmw == original dmw here here // dmw == marked_dmw here
if (dmw->is_marked()) if (dmw->is_marked())
unmark dmw dmw unmark dmw
obj = object() obj = object()
obj->cas_set_mark(dmw, this) obj->cas_set_mark(dmw, this)
T-enter object T-deflate
------------------------------------------- +-------------+ ------- T-enter object T-deflate
-----------------------------------------
install_displaced_markword_in_object() { | mark=dmw | install_displaced_markword_in_object() {
dmw = header() +-------------+ -----------------------------------------
dmw = header()
| mark=dmw | dmw = header()
if (!dmw->is_marked() && +-------------+ marked() && if (!dmw->is_marked() &&
dmw->hash() == 0) { dmw->hash() == 0) {
create marked_dmw dmw create marked_dmw
dmw = cmpxchg(marked_dmw, &header, dmw) dmw = cmpxchg(marked_dmw, &header, dmw)
} }
// dmw == ... // dmw == ...
if (dmw->is_marked()) if (dmw->is_marked())
unmark dmw dmw unmark dmw
obj = object() obj = object()
obj->cas_set_mark(dmw, this) obj->cas_set_mark(dmw, this)
...
T-hash ObjectMonitor T-deflate
------------------------ +-----------------------+ --------------------------------------------
save_om_ptr() { | header=dmw_no_hash | deflate_monitor_using_JT() {
atomic inc ref_count | owner=DEFLATER_MARKER | cmpxchg(DEFLATER_MARKER, &owner, NULL)
if (owner == | contentions=0 | if (waiters != 0 || ref_count != 0) {
DEFLATER_MARKER && | ref_count=1 | }
contentions <= 0) { +-----------------------+ 1> prev = cmpxchg(-max_jint, &contentions, 0)
} || 2> if (prev == 0 &&
1> if (object no longer \/ owner == DEFLATER_MARKER &&
has a monitor or +-----------------------+ ref_count == 0) {
is a different | header=dmw_no_hash | } else {
monitor) { | owner=DEFLATER_MARKER | cmpxchg(NULL, &owner, DEFLATER_MARKER)
atomic dec ref_count | contentions=-max_jint | atomic add max_jint to contentions
return false to | ref_count=1 | 3> bailout on deflation
cause a retry +-----------------------+ }
} ||
2> save om_ptr in the \/
ObjectMonitorHandle +-----------------------+
} | header=dmw_hash |
if save_om_ptr() { | owner=NULL |
if no hash | contentions=0 |
gen hash & merge | ref_count=1 |
hash = hash(header) +-----------------------+
}
3> atomic dec ref_count
return hash
...