src/hotspot/share/gc/z/zNMethod.cpp
changeset 57490 7826a2a06f87
parent 55499 1887e16a5657
child 58226 408c445d04e8
--- a/src/hotspot/share/gc/z/zNMethod.cpp	Thu Jul 18 13:41:55 2019 +0800
+++ b/src/hotspot/share/gc/z/zNMethod.cpp	Thu Jul 18 11:15:20 2019 +0200
@@ -261,6 +261,24 @@
     Atomic::store(true, &_failed);
   }
 
+  void unlink(nmethod* nm) {
+    // Unlinking of the dependencies must happen before the
+    // handshake separating unlink and purge.
+    nm->flush_dependencies(false /* delete_immediately */);
+
+    // We don't need to take the lock when unlinking nmethods from
+    // the Method, because it is only concurrently unlinked by
+    // the entry barrier, which acquires the per nmethod lock.
+    nm->unlink_from_method(false /* acquire_lock */);
+
+    if (nm->is_osr_method()) {
+      // Invalidate the osr nmethod before the handshake. The nmethod
+      // will be made unloaded after the handshake. Then invalidate_osr_method()
+      // will be called again, which will be a no-op.
+      nm->invalidate_osr_method();
+    }
+  }
+
 public:
   ZNMethodUnlinkClosure(bool unloading_occurred) :
       _unloading_occurred(unloading_occurred),
@@ -278,14 +296,7 @@
     ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
 
     if (nm->is_unloading()) {
-      // Unlinking of the dependencies must happen before the
-      // handshake separating unlink and purge.
-      nm->flush_dependencies(false /* delete_immediately */);
-
-      // We don't need to take the lock when unlinking nmethods from
-      // the Method, because it is only concurrently unlinked by
-      // the entry barrier, which acquires the per nmethod lock.
-      nm->unlink_from_method(false /* acquire_lock */);
+      unlink(nm);
       return;
     }