< prev index next >
src/hotspot/share/code/nmethod.cpp
Print this page
*** 1659,1682 ****
// Even if it is the end of the linked list, it will have a non-null link value,
// as long as it is on the list.
// This code must be MP safe, because it is used from parallel GC passes.
bool nmethod::test_set_oops_do_mark() {
assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
! nmethod* observed_mark_link = _oops_do_mark_link;
! if (observed_mark_link == NULL) {
// Claim this nmethod for this thread to mark.
! observed_mark_link = (nmethod*)
! Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_link, NULL);
! if (observed_mark_link == NULL) {
!
// Atomically append this nmethod (now claimed) to the head of the list:
nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
for (;;) {
nmethod* required_mark_nmethods = observed_mark_nmethods;
_oops_do_mark_link = required_mark_nmethods;
! observed_mark_nmethods = (nmethod*)
! Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods);
if (observed_mark_nmethods == required_mark_nmethods)
break;
}
// Mark was clear when we first saw this guy.
if (TraceScavenge) { print_on(tty, "oops_do, mark"); }
--- 1659,1678 ----
// Even if it is the end of the linked list, it will have a non-null link value,
// as long as it is on the list.
// This code must be MP safe, because it is used from parallel GC passes.
bool nmethod::test_set_oops_do_mark() {
assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
! if (_oops_do_mark_link == NULL) {
// Claim this nmethod for this thread to mark.
! if (Atomic::cmpxchg(NMETHOD_SENTINEL, &_oops_do_mark_link, (nmethod*)NULL) == NULL) {
// Atomically append this nmethod (now claimed) to the head of the list:
nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
for (;;) {
nmethod* required_mark_nmethods = observed_mark_nmethods;
_oops_do_mark_link = required_mark_nmethods;
! observed_mark_nmethods =
! Atomic::cmpxchg(this, &_oops_do_mark_nmethods, required_mark_nmethods);
if (observed_mark_nmethods == required_mark_nmethods)
break;
}
// Mark was clear when we first saw this guy.
if (TraceScavenge) { print_on(tty, "oops_do, mark"); }
*** 1688,1700 ****
}
void nmethod::oops_do_marking_prologue() {
if (TraceScavenge) { tty->print_cr("[oops_do_marking_prologue"); }
assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
! // We use cmpxchg_ptr instead of regular assignment here because the user
// may fork a bunch of threads, and we need them all to see the same state.
! void* observed = Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, NULL);
guarantee(observed == NULL, "no races in this sequential code");
}
void nmethod::oops_do_marking_epilogue() {
assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
--- 1684,1696 ----
}
void nmethod::oops_do_marking_prologue() {
if (TraceScavenge) { tty->print_cr("[oops_do_marking_prologue"); }
assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
! // We use cmpxchg instead of regular assignment here because the user
// may fork a bunch of threads, and we need them all to see the same state.
! nmethod* observed = Atomic::cmpxchg(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, (nmethod*)NULL);
guarantee(observed == NULL, "no races in this sequential code");
}
void nmethod::oops_do_marking_epilogue() {
assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
*** 1705,1716 ****
cur->_oops_do_mark_link = NULL;
DEBUG_ONLY(cur->verify_oop_relocations());
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
cur = next;
}
! void* required = _oops_do_mark_nmethods;
! void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required);
guarantee(observed == required, "no races in this sequential code");
if (TraceScavenge) { tty->print_cr("oops_do_marking_epilogue]"); }
}
class DetectScavengeRoot: public OopClosure {
--- 1701,1712 ----
cur->_oops_do_mark_link = NULL;
DEBUG_ONLY(cur->verify_oop_relocations());
NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark"));
cur = next;
}
! nmethod* required = _oops_do_mark_nmethods;
! nmethod* observed = Atomic::cmpxchg((nmethod*)NULL, &_oops_do_mark_nmethods, required);
guarantee(observed == required, "no races in this sequential code");
if (TraceScavenge) { tty->print_cr("oops_do_marking_epilogue]"); }
}
class DetectScavengeRoot: public OopClosure {
< prev index next >