< prev index next >
src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp
Print this page
rev 10509 : [backport] Refactor and improve ShenandoahCodeRoots strategies
rev 10619 : [backport] Move ParallelCodeIterator to ShenandoahCodeRoots
rev 10630 : [backport] Unreachable assert in ShenandoahCodeRoots::acquire_lock
*** 32,46 ****
class ShenandoahHeap;
class ShenandoahHeapRegion;
class ShenandoahCodeRootsLock;
class ShenandoahCodeRootsIterator VALUE_OBJ_CLASS_SPEC {
friend class ShenandoahCodeRoots;
protected:
ShenandoahHeap* _heap;
! ParallelCodeCacheIterator _par_iterator;
ShenandoahSharedFlag _seq_claimed;
volatile jlong _claimed;
protected:
ShenandoahCodeRootsIterator();
~ShenandoahCodeRootsIterator();
--- 32,84 ----
class ShenandoahHeap;
class ShenandoahHeapRegion;
class ShenandoahCodeRootsLock;
+ class ShenandoahParallelCodeCacheIterator VALUE_OBJ_CLASS_SPEC {
+ friend class CodeCache;
+ private:
+ volatile int _claimed_idx;
+ volatile bool _finished;
+ public:
+ ShenandoahParallelCodeCacheIterator();
+ void parallel_blobs_do(CodeBlobClosure* f);
+ };
+
+ // ShenandoahNMethod tuple records the internal locations of oop slots within the nmethod.
+ // This allows us to quickly scan the oops without doing the nmethod-internal scans, that
+ // sometimes involves parsing the machine code. Note it does not record the oops themselves,
+ // because it would then require handling these tuples as the new class of roots.
+ class ShenandoahNMethod : public CHeapObj<mtGC> {
+ private:
+ nmethod* _nm;
+ oop** _oops;
+ int _oops_count;
+
+ public:
+ ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>* oops);
+ ~ShenandoahNMethod();
+
+ nmethod* nm() {
+ return _nm;
+ }
+
+ bool has_cset_oops(ShenandoahHeap* heap);
+
+ void assert_alive_and_correct() PRODUCT_RETURN;
+ void assert_same_oops(GrowableArray<oop*>* oops) PRODUCT_RETURN;
+
+ static bool find_with_nmethod(void* nm, ShenandoahNMethod* other) {
+ return other->_nm == nm;
+ }
+ };
+
class ShenandoahCodeRootsIterator VALUE_OBJ_CLASS_SPEC {
friend class ShenandoahCodeRoots;
protected:
ShenandoahHeap* _heap;
! ShenandoahParallelCodeCacheIterator _par_iterator;
ShenandoahSharedFlag _seq_claimed;
volatile jlong _claimed;
protected:
ShenandoahCodeRootsIterator();
~ShenandoahCodeRootsIterator();
*** 85,102 ****
* @return
*/
static ShenandoahCsetCodeRootsIterator cset_iterator();
private:
! static volatile jint _recorded_nmethods_lock;
! static GrowableArray<nmethod*>* _recorded_nmethods;
!
! static void fast_add_nmethod(nmethod* nm);
! static void fast_remove_nmethod(nmethod* nm);
static void acquire_lock(bool write) {
! volatile jint* loc = &_recorded_nmethods_lock;
if (write) {
while ((OrderAccess::load_acquire(loc) != 0) ||
Atomic::cmpxchg(-1, loc, 0) != 0) {
SpinPause();
}
--- 123,137 ----
* @return
*/
static ShenandoahCsetCodeRootsIterator cset_iterator();
private:
! static volatile jint _recorded_nms_lock;
! static GrowableArray<ShenandoahNMethod*>* _recorded_nms;
static void acquire_lock(bool write) {
! volatile jint* loc = &_recorded_nms_lock;
if (write) {
while ((OrderAccess::load_acquire(loc) != 0) ||
Atomic::cmpxchg(-1, loc, 0) != 0) {
SpinPause();
}
*** 105,125 ****
while (true) {
jint cur = OrderAccess::load_acquire(loc);
if (cur >= 0) {
if (Atomic::cmpxchg(cur + 1, loc, cur) == cur) {
// Success!
return;
}
}
SpinPause();
}
- assert (*loc > 1, "acquired for read");
}
}
static void release_lock(bool write) {
! volatile jint* loc = &ShenandoahCodeRoots::_recorded_nmethods_lock;
if (write) {
OrderAccess::release_store_fence(loc, 0);
} else {
Atomic::dec(loc);
}
--- 140,160 ----
while (true) {
jint 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 jint* loc = &ShenandoahCodeRoots::_recorded_nms_lock;
if (write) {
OrderAccess::release_store_fence(loc, 0);
} else {
Atomic::dec(loc);
}
< prev index next >