< prev index next >

src/hotspot/share/code/nmethodBarrier.cpp

Concurrent class unloading

*** 29,46 **** #include "gc/shared/barrierSet.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" ! #include "runtime/thread.hpp" #include "utilities/debug.hpp" #include "utilities/spinYield.hpp" bool nmethodBarrierState::is_safe() const { ! CounterUnion twin_value; ! twin_value._value = Atomic::load(&_state); ! return twin_value._counters._lock > 0; } bool nmethodBarrierState::enter() { while (true) { CounterUnion old; --- 29,44 ---- #include "gc/shared/barrierSet.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" ! #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" #include "utilities/spinYield.hpp" bool nmethodBarrierState::is_safe() const { ! return Thread::current()->in_nmethod_entry_barrier(); } bool nmethodBarrierState::enter() { while (true) { CounterUnion old; ***************
*** 49,70 **** --- 47,72 ---- CounterUnion next; next._value = old._value; int disarmed_value = nmethodBarrier::disarmed_value(); + assert(disarmed_value != 0, "sanity"); + if (old._counters._epoch != disarmed_value) { next._counters._epoch = disarmed_value; next._counters._lock = 1; } else if (old._counters._lock == 0) { return false; } else { ++next._counters._lock; } assert(next._counters._lock > 0, "check"); + assert(next._counters._epoch == nmethodBarrier::disarmed_value(), "sanity"); if (Atomic::cmpxchg(next._value, &_state, old._value) == old._value) { + Thread::current()->set_is_in_nmethod_entry_barrier(true); return true; } } } ***************
*** 76,86 **** --- 78,93 ---- CounterUnion next; next._value = old._value; --next._counters._lock; + assert(old._counters._epoch == nmethodBarrier::disarmed_value(), "sanity"); + assert(old._counters._lock > 0, "check"); + assert(next._counters._lock >= 0, "check"); + if (Atomic::cmpxchg(next._value, &_state, old._value) == old._value) { + Thread::current()->set_is_in_nmethod_entry_barrier(false); return; } } } ***************
*** 117,133 **** nmethod* nm = cb->as_nmethod(); nmethodBarrier nmbarrier(nm, return_address_ptr); return bs->on_nmethod_entry_barrier(nm, &nmbarrier) ? 0 : 1; } - void nmethodBarrier::initialize(nmethod* nm) { - BarrierSet* bs = BarrierSet::barrier_set(); - if (bs->needs_nmethod_entry_barrier()) { - nm->disarm_barrier(); - } - } - void nmethodBarrier::disarm() { _nm->disarm_barrier(); // multiple threads can enter the barrier at the same time while armed // one can finish and decide that the barrier can be disarmed, in the meantime the other // have made the same decision continued on and deoptimized on something else. --- 124,133 ---- ***************
*** 135,144 **** assert(!_is_deoptimized, "can only disarm methods that didn't deoptimize!"); } int nmethodBarrier::disarmed_value() { BarrierSet* bs = BarrierSet::barrier_set(); Thread* thread = Thread::current(); ! int* state_addr = reinterpret_cast<int*>(reinterpret_cast<char*>(thread) + ! in_bytes(bs->nmethod_entry_barrier_state_thread_offset())); ! return *state_addr; } --- 135,150 ---- assert(!_is_deoptimized, "can only disarm methods that didn't deoptimize!"); } int nmethodBarrier::disarmed_value() { BarrierSet* bs = BarrierSet::barrier_set(); + int value = bs->nmethod_entry_barrier_state(); + #ifdef ASSERT Thread* thread = Thread::current(); ! if (thread->is_Java_thread()) { ! int* state_addr = reinterpret_cast<int*>(reinterpret_cast<char*>(thread) + ! in_bytes(bs->nmethod_entry_barrier_state_thread_offset())); ! assert(*state_addr == value, "global and local values out of sync"); ! } ! #endif ! return value; }
< prev index next >