< 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 >