< prev index next >

src/hotspot/share/code/nmethod.cpp

   if (PrintCompilation && _state != unloaded) {
     print_on(tty, state_msg);
   }
 }
 
+void nmethod::unlink_from_method(bool acquire_lock) {
+  // We need to check if both the _code and _from_compiled_code_entry_point
+  // refer to this nmethod because there is a race in setting these two fields
+  // in Method* as seen in bugid 4947125.
+  // If the vep() points to the zombie nmethod, the memory for the nmethod
+  // could be flushed and the compiler and vtable stubs could still call
+  // through it.
+  if (method() != NULL && (method()->code() == this ||
+                           method()->from_compiled_entry() == verified_entry_point())) {
+    method()->clear_code(acquire_lock);
+  }
+}
+
 /**
  * Common functionality for both make_not_entrant and make_zombie
  */
 bool nmethod::make_not_entrant_or_zombie(int state) {
   assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");

@@ -1244,21 +1257,11 // Invalidate while holding the patching lock JVMCI_ONLY(maybe_invalidate_installed_code()); // Remove nmethod from method. - // We need to check if both the _code and _from_compiled_code_entry_point - // refer to this nmethod because there is a race in setting these two fields - // in Method* as seen in bugid 4947125. - // If the vep() points to the zombie nmethod, the memory for the nmethod - // could be flushed and the compiler and vtable stubs could still call - // through it. - if (method() != NULL && (method()->code() == this || - method()->from_compiled_entry() == verified_entry_point())) { - HandleMark hm; - method()->clear_code(false /* already owns Patching_lock */); - } + unlink_from_method(false /* already owns Patching_lock */); } // 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
< prev index next >