changeset 59246:de30eb1867e3

8234654: ZGC: Only disarm NMethods when marking/relocating code roots Reviewed-by: eosterlund, stefank
author pliden
date Tue, 10 Dec 2019 13:39:38 +0100
parents 9f4e98d4dcd4
children 88799f0b0f82 de502a45751f
files src/hotspot/share/gc/z/zMark.cpp src/hotspot/share/gc/z/zNMethod.cpp src/hotspot/share/gc/z/zNMethod.hpp src/hotspot/share/gc/z/zRelocate.cpp src/hotspot/share/gc/z/zRootsIterator.cpp src/hotspot/share/gc/z/zRootsIterator.hpp
diffstat 6 files changed, 50 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/z/zMark.cpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zMark.cpp	Tue Dec 10 13:39:38 2019 +0100
@@ -140,6 +140,10 @@
     ZThreadLocalAllocBuffer::retire(thread);
   }
 
+  virtual bool should_disarm_nmethods() const {
+    return true;
+  }
+
   virtual void do_oop(oop* p) {
     ZBarrier::mark_barrier_on_root_oop_field(p);
   }
--- a/src/hotspot/share/gc/z/zNMethod.cpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethod.cpp	Tue Dec 10 13:39:38 2019 +0100
@@ -163,7 +163,7 @@
   ZNMethodTable::register_nmethod(nm);
 
   // Disarm nmethod entry barrier
-  disarm_nmethod(nm);
+  disarm(nm);
 }
 
 void ZNMethod::unregister_nmethod(nmethod* nm) {
@@ -187,7 +187,16 @@
   delete gc_data(nm);
 }
 
-void ZNMethod::disarm_nmethod(nmethod* nm) {
+bool ZNMethod::is_armed(nmethod* nm) {
+  BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
+  if (bs != NULL) {
+    return bs->is_armed(nm);
+  }
+
+  return false;
+}
+
+void ZNMethod::disarm(nmethod* nm) {
   BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
   if (bs != NULL) {
     bs->disarm(nm);
@@ -301,10 +310,12 @@
 
     ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
 
-    // Heal oops and disarm
-    ZNMethodOopClosure cl;
-    ZNMethod::nmethod_oops_do(nm, &cl);
-    ZNMethod::disarm_nmethod(nm);
+    if (ZNMethod::is_armed(nm)) {
+      // Heal oops and disarm
+      ZNMethodOopClosure cl;
+      ZNMethod::nmethod_oops_do(nm, &cl);
+      ZNMethod::disarm(nm);
+    }
 
     // Clear compiled ICs and exception caches
     if (!nm->unload_nmethod_caches(_unloading_occurred)) {
--- a/src/hotspot/share/gc/z/zNMethod.hpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethod.hpp	Tue Dec 10 13:39:38 2019 +0100
@@ -43,7 +43,8 @@
   static void unregister_nmethod(nmethod* nm);
   static void flush_nmethod(nmethod* nm);
 
-  static void disarm_nmethod(nmethod* nm);
+  static bool is_armed(nmethod* nm);
+  static void disarm(nmethod* nm);
 
   static void nmethod_oops_do(nmethod* nm, OopClosure* cl);
 
--- a/src/hotspot/share/gc/z/zRelocate.cpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocate.cpp	Tue Dec 10 13:39:38 2019 +0100
@@ -56,6 +56,10 @@
     ZThreadLocalAllocBuffer::remap(thread);
   }
 
+  virtual bool should_disarm_nmethods() const {
+    return true;
+  }
+
   virtual void do_oop(oop* p) {
     ZBarrier::relocate_barrier_on_root_oop_field(p);
   }
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp	Tue Dec 10 13:39:38 2019 +0100
@@ -139,27 +139,31 @@
   }
 }
 
-class ZRootsIteratorCodeBlobClosure : public CodeBlobToOopClosure {
+class ZRootsIteratorCodeBlobClosure : public CodeBlobClosure {
 private:
-  BarrierSetNMethod* _bs;
+  ZRootsIteratorClosure* const _cl;
+  const bool                   _should_disarm_nmethods;
 
 public:
-  ZRootsIteratorCodeBlobClosure(OopClosure* cl) :
-    CodeBlobToOopClosure(cl, true /* fix_relocations */),
-    _bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
+  ZRootsIteratorCodeBlobClosure(ZRootsIteratorClosure* cl) :
+    _cl(cl),
+    _should_disarm_nmethods(cl->should_disarm_nmethods()) {}
 
   virtual void do_code_blob(CodeBlob* cb) {
     nmethod* const nm = cb->as_nmethod_or_null();
     if (nm != NULL && nm->oops_do_try_claim()) {
-      CodeBlobToOopClosure::do_code_blob(cb);
-      _bs->disarm(nm);
+      ZNMethod::nmethod_oops_do(nm, _cl);
+      assert(ZNMethod::is_armed(nm) == _should_disarm_nmethods, "Invalid state");
+      if (_should_disarm_nmethods) {
+        ZNMethod::disarm(nm);
+      }
     }
   }
 };
 
 class ZRootsIteratorThreadClosure : public ThreadClosure {
 private:
-  ZRootsIteratorClosure* _cl;
+  ZRootsIteratorClosure* const _cl;
 
 public:
   ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) :
--- a/src/hotspot/share/gc/z/zRootsIterator.hpp	Tue Dec 10 13:12:25 2019 +0100
+++ b/src/hotspot/share/gc/z/zRootsIterator.hpp	Tue Dec 10 13:39:38 2019 +0100
@@ -31,10 +31,7 @@
 #include "runtime/thread.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-class ZRootsIteratorClosure : public OopClosure {
-public:
-  virtual void do_thread(Thread* thread) {}
-};
+class ZRootsIteratorClosure;
 
 typedef OopStorage::ParState<true /* concurrent */, false /* is_const */> ZOopStorageIterator;
 
@@ -82,9 +79,18 @@
   void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
 };
 
+class ZRootsIteratorClosure : public OopClosure {
+public:
+  virtual void do_thread(Thread* thread) {}
+
+  virtual bool should_disarm_nmethods() const {
+    return false;
+  }
+};
+
 class ZRootsIterator {
 private:
-  bool _visit_jvmti_weak_export;
+  const bool _visit_jvmti_weak_export;
 
   void do_universe(ZRootsIteratorClosure* cl);
   void do_object_synchronizer(ZRootsIteratorClosure* cl);