< prev index next >

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

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

@@ -611,5 +611,31 @@
   assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(),
          "Only for concurrent class unloading");
   _table->finish_iteration(_table_snapshot);
   CodeCache_lock->notify_all();
 }
+
+ShenandoahAbortableNMethodLocker::ShenandoahAbortableNMethodLocker(ShenandoahReentrantLock* lock) :
+  _heap(ShenandoahHeap::heap()), _lock(lock), _aborted(false) {
+  while (!_aborted) {
+    // Try lock first. Because we really don't want to abort,
+    // which may result massive deopt. from nmethod entry barrier
+    if (_lock->try_lock()) {
+      break;
+    } else if (_heap->cancelled_gc()) {
+      _aborted = true;
+    } else {
+      // Spin a little. Since the lock is per-nmethod, we can expect the other
+      // thread to release the lock fair soon.
+      for (int i = 0; i < 4096; i ++) {
+        SpinPause();
+      }
+    }
+  }
+}
+
+ShenandoahAbortableNMethodLocker::~ShenandoahAbortableNMethodLocker() {
+  if (_lock != NULL && !_aborted) {
+    assert(_lock->owned_by_self(), "Must be owner");
+    _lock->unlock();
+  }
+}
< prev index next >