changeset 10544:a264a8ff29b0

Merge
author thartmann
date Wed, 30 Mar 2016 12:34:08 +0200
parents 4bf8a911582b d7915089dde3
children 1b8ecaab2482 03fb00b96355
files src/share/vm/code/nmethod.cpp src/share/vm/runtime/sweeper.cpp
diffstat 2 files changed, 28 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/code/nmethod.cpp	Tue Mar 29 22:39:17 2016 +0000
+++ b/src/share/vm/code/nmethod.cpp	Wed Mar 30 12:34:08 2016 +0200
@@ -1331,8 +1331,19 @@
   }
   // Unlink the osr method, so we do not look this up again
   if (is_osr_method()) {
-    invalidate_osr_method();
+    // Invalidate the osr nmethod only once
+    if (is_in_use()) {
+      invalidate_osr_method();
+    }
+#ifdef ASSERT
+    if (method() != NULL) {
+      // Make sure osr nmethod is invalidated, i.e. not on the list
+      bool found = method()->method_holder()->remove_osr_nmethod(this);
+      assert(!found, "osr nmethod should have been invalidated");
+    }
+#endif
   }
+
   // If _method is already NULL the Method* is about to be unloaded,
   // so we don't have to break the cycle. Note that it is possible to
   // have the Method* live here, in case we unload the nmethod because
@@ -1385,16 +1396,9 @@
 
 void nmethod::invalidate_osr_method() {
   assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
-#ifndef ASSERT
-  // Make sure osr nmethod is invalidated only once
-  if (!is_in_use()) {
-    return;
-  }
-#endif
   // Remove from list of active nmethods
   if (method() != NULL) {
-    bool removed = method()->method_holder()->remove_osr_nmethod(this);
-    assert(!removed || is_in_use(), "unused osr nmethod should be invalidated");
+    method()->method_holder()->remove_osr_nmethod(this);
   }
 }
 
@@ -1443,8 +1447,9 @@
     // invalidate osr nmethod before acquiring the patching lock since
     // they both acquire leaf locks and we don't want a deadlock.
     // This logic is equivalent to the logic below for patching the
-    // verified entry point of regular methods.
-    if (is_osr_method()) {
+    // verified entry point of regular methods. We check that the
+    // nmethod is in use to ensure that it is invalidated only once.
+    if (is_osr_method() && is_in_use()) {
       // this effectively makes the osr nmethod not entrant
       invalidate_osr_method();
     }
@@ -1510,6 +1515,14 @@
     }
   } // leave critical region under Patching_lock
 
+#ifdef ASSERT
+  if (is_osr_method() && method() != NULL) {
+    // Make sure osr nmethod is invalidated, i.e. not on the list
+    bool found = method()->method_holder()->remove_osr_nmethod(this);
+    assert(!found, "osr nmethod should have been invalidated");
+  }
+#endif
+
   // When the nmethod becomes zombie it is no longer alive so the
   // dependencies must be flushed.  nmethods in the not_entrant
   // state will be flushed later when the transition to zombie
--- a/src/share/vm/runtime/sweeper.cpp	Tue Mar 29 22:39:17 2016 +0000
+++ b/src/share/vm/runtime/sweeper.cpp	Wed Mar 30 12:34:08 2016 +0200
@@ -613,7 +613,10 @@
       // Code cache state change is tracked in make_zombie()
       nm->make_zombie();
       SWEEP(nm);
-      if (nm->is_osr_method()) {
+      // The nmethod may have been locked by JVMTI after being made zombie (see
+      // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot
+      // flush the osr nmethod directly but have to wait for a later sweeper cycle.
+      if (nm->is_osr_method() && !nm->is_locked_by_vm()) {
         // No inline caches will ever point to osr methods, so we can just remove it.
         // Make sure that we unregistered the nmethod with the heap and flushed all
         // dependencies before removing the nmethod (done in make_zombie()).