8224115: Shenandoah: Eliminate RWLock that protects recorded nmethod data array
Reviewed-by: shade
This commit is contained in:
parent
96c9fcf22f
commit
deaba32229
@ -120,15 +120,14 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
|
|
||||||
GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
|
GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
|
||||||
|
|
||||||
void ShenandoahCodeRoots::initialize() {
|
void ShenandoahCodeRoots::initialize() {
|
||||||
_recorded_nms_lock._lock = 0;
|
|
||||||
_recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
|
_recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
|
void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
|
||||||
|
assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock");
|
||||||
switch (ShenandoahCodeRootsStyle) {
|
switch (ShenandoahCodeRootsStyle) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
@ -140,9 +139,6 @@ void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
|
|||||||
if (detector.has_oops()) {
|
if (detector.has_oops()) {
|
||||||
ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
|
ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
|
||||||
nmr->assert_alive_and_correct();
|
nmr->assert_alive_and_correct();
|
||||||
|
|
||||||
ShenandoahCodeRootsLock lock(true);
|
|
||||||
|
|
||||||
int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
|
int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
ShenandoahNMethod* old = _recorded_nms->at(idx);
|
ShenandoahNMethod* old = _recorded_nms->at(idx);
|
||||||
@ -160,6 +156,7 @@ void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) {
|
void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) {
|
||||||
|
assert(CodeCache_lock->owned_by_self(), "Must own CodeCache_lock");
|
||||||
switch (ShenandoahCodeRootsStyle) {
|
switch (ShenandoahCodeRootsStyle) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1: {
|
case 1: {
|
||||||
@ -170,8 +167,6 @@ void ShenandoahCodeRoots::remove_nmethod(nmethod* nm) {
|
|||||||
nm->oops_do(&detector, /* allow_zombie = */ true);
|
nm->oops_do(&detector, /* allow_zombie = */ true);
|
||||||
|
|
||||||
if (detector.has_oops()) {
|
if (detector.has_oops()) {
|
||||||
ShenandoahCodeRootsLock lock(true);
|
|
||||||
|
|
||||||
int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
|
int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
|
||||||
assert(idx != -1, "nmethod " PTR_FORMAT " should be registered", p2i(nm));
|
assert(idx != -1, "nmethod " PTR_FORMAT " should be registered", p2i(nm));
|
||||||
ShenandoahNMethod* old = _recorded_nms->at(idx);
|
ShenandoahNMethod* old = _recorded_nms->at(idx);
|
||||||
@ -199,7 +194,7 @@ ShenandoahCodeRootsIterator::ShenandoahCodeRootsIterator() :
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
ShenandoahCodeRoots::acquire_lock(false);
|
CodeCache_lock->lock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -215,7 +210,7 @@ ShenandoahCodeRootsIterator::~ShenandoahCodeRootsIterator() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
ShenandoahCodeRoots::release_lock(false);
|
CodeCache_lock->unlock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
class ShenandoahHeap;
|
class ShenandoahHeap;
|
||||||
class ShenandoahHeapRegion;
|
class ShenandoahHeapRegion;
|
||||||
class ShenandoahCodeRootsLock;
|
|
||||||
|
|
||||||
class ShenandoahParallelCodeHeapIterator {
|
class ShenandoahParallelCodeHeapIterator {
|
||||||
friend class CodeCache;
|
friend class CodeCache;
|
||||||
@ -124,7 +123,6 @@ public:
|
|||||||
|
|
||||||
class ShenandoahCodeRoots : public CHeapObj<mtGC> {
|
class ShenandoahCodeRoots : public CHeapObj<mtGC> {
|
||||||
friend class ShenandoahHeap;
|
friend class ShenandoahHeap;
|
||||||
friend class ShenandoahCodeRootsLock;
|
|
||||||
friend class ShenandoahCodeRootsIterator;
|
friend class ShenandoahCodeRootsIterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -133,61 +131,7 @@ public:
|
|||||||
static void remove_nmethod(nmethod* nm);
|
static void remove_nmethod(nmethod* nm);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PaddedLock {
|
|
||||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int));
|
|
||||||
volatile int _lock;
|
|
||||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
static PaddedLock _recorded_nms_lock;
|
|
||||||
static GrowableArray<ShenandoahNMethod*>* _recorded_nms;
|
static GrowableArray<ShenandoahNMethod*>* _recorded_nms;
|
||||||
|
|
||||||
static void acquire_lock(bool write) {
|
|
||||||
volatile int* loc = &_recorded_nms_lock._lock;
|
|
||||||
if (write) {
|
|
||||||
while ((OrderAccess::load_acquire(loc) != 0) ||
|
|
||||||
Atomic::cmpxchg(-1, loc, 0) != 0) {
|
|
||||||
SpinPause();
|
|
||||||
}
|
|
||||||
assert (*loc == -1, "acquired for write");
|
|
||||||
} else {
|
|
||||||
while (true) {
|
|
||||||
int cur = OrderAccess::load_acquire(loc);
|
|
||||||
if (cur >= 0) {
|
|
||||||
if (Atomic::cmpxchg(cur + 1, loc, cur) == cur) {
|
|
||||||
// Success!
|
|
||||||
assert (*loc > 0, "acquired for read");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpinPause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void release_lock(bool write) {
|
|
||||||
volatile int* loc = &ShenandoahCodeRoots::_recorded_nms_lock._lock;
|
|
||||||
if (write) {
|
|
||||||
OrderAccess::release_store_fence(loc, 0);
|
|
||||||
} else {
|
|
||||||
Atomic::dec(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Very simple unranked read-write lock
|
|
||||||
class ShenandoahCodeRootsLock : public StackObj {
|
|
||||||
friend class ShenandoahCodeRoots;
|
|
||||||
private:
|
|
||||||
const bool _write;
|
|
||||||
public:
|
|
||||||
ShenandoahCodeRootsLock(bool write) : _write(write) {
|
|
||||||
ShenandoahCodeRoots::acquire_lock(write);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ShenandoahCodeRootsLock() {
|
|
||||||
ShenandoahCodeRoots::release_lock(_write);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP
|
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user