< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp

Print this page
rev 59811 : 8247670: Shenandoah: deadlock during class unloading OOME


 596 
 597 void ShenandoahConcurrentNMethodIterator::nmethods_do_begin() {
 598   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 599   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
 600          "Only for concurrent class unloading");
 601   _table_snapshot = _table->snapshot_for_iteration();
 602 }
 603 
 604 void ShenandoahConcurrentNMethodIterator::nmethods_do(NMethodClosure* cl) {
 605   assert(_table_snapshot != NULL, "Must first call nmethod_do_begin()");
 606   _table_snapshot->concurrent_nmethods_do(cl);
 607 }
 608 
 609 void ShenandoahConcurrentNMethodIterator::nmethods_do_end() {
 610   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 611   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
 612          "Only for concurrent class unloading");
 613   _table->finish_iteration(_table_snapshot);
 614   CodeCache_lock->notify_all();
 615 }




























 596 
 597 void ShenandoahConcurrentNMethodIterator::nmethods_do_begin() {
 598   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 599   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
 600          "Only for concurrent class unloading");
 601   _table_snapshot = _table->snapshot_for_iteration();
 602 }
 603 
 604 void ShenandoahConcurrentNMethodIterator::nmethods_do(NMethodClosure* cl) {
 605   assert(_table_snapshot != NULL, "Must first call nmethod_do_begin()");
 606   _table_snapshot->concurrent_nmethods_do(cl);
 607 }
 608 
 609 void ShenandoahConcurrentNMethodIterator::nmethods_do_end() {
 610   assert(CodeCache_lock->owned_by_self(), "Lock must be held");
 611   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
 612          "Only for concurrent class unloading");
 613   _table->finish_iteration(_table_snapshot);
 614   CodeCache_lock->notify_all();
 615 }
 616 
 617 ShenandoahAbortableNMethodLocker::ShenandoahAbortableNMethodLocker(ShenandoahReentrantLock* lock) :
 618   _heap(ShenandoahHeap::heap()), _lock(lock), _aborted(false) {
 619   while (!_aborted) {
 620     // Try lock first. Because we really don't want to abort,
 621     // which may result massive deopt. from nmethod entry barrier
 622     if (_lock->try_lock()) {
 623       break;
 624     } else if (_heap->cancelled_gc()) {
 625       _aborted = true;
 626     } else {
 627       // Spin a little. Since the lock is per-nmethod, we can expect the other
 628       // thread to release the lock fair soon.
 629       for (int i = 0; i < 4096; i ++) {
 630         SpinPause();
 631       }
 632     }
 633   }
 634 }
 635 
 636 ShenandoahAbortableNMethodLocker::~ShenandoahAbortableNMethodLocker() {
 637   if (_lock != NULL && !_aborted) {
 638     assert(_lock->owned_by_self(), "Must be owner");
 639     _lock->unlock();
 640   }
 641 }
< prev index next >