8223215: Shenandoah: Support verifying subset of roots
authorzgu
Wed, 15 May 2019 08:58:23 -0400
changeset 54882 b99e97bc5040
parent 54881 80991d58b947
child 54883 4ee117b890c5
8223215: Shenandoah: Support verifying subset of roots Reviewed-by: shade, rkennke
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp
src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp
src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp
src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed May 15 14:30:22 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed May 15 08:58:23 2019 -0400
@@ -2145,6 +2145,9 @@
   retire_and_reset_gclabs();
 
   if (ShenandoahVerify) {
+    if (!is_degenerated_gc_in_progress()) {
+      verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots);
+    }
     verifier()->verify_before_updaterefs();
   }
 
@@ -2182,6 +2185,10 @@
   }
   assert(!cancelled_gc(), "Should have been done right before");
 
+  if (ShenandoahVerify && !is_degenerated_gc_in_progress()) {
+    verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots);
+  }
+
   concurrent_mark()->update_roots(is_degenerated_gc_in_progress() ?
                                   ShenandoahPhaseTimings::degen_gc_update_roots:
                                   ShenandoahPhaseTimings::final_update_refs_roots);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Wed May 15 14:30:22 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Wed May 15 08:58:23 2019 -0400
@@ -75,32 +75,6 @@
   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
 }
 
-void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
-  CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
-  CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
-
-  CodeCache::blobs_do(&blobs);
-  ClassLoaderDataGraph::cld_do(&clds);
-  Universe::oops_do(oops);
-  Management::oops_do(oops);
-  JvmtiExport::oops_do(oops);
-  JNIHandles::oops_do(oops);
-  ObjectSynchronizer::oops_do(oops);
-  SystemDictionary::oops_do(oops);
-
-  AlwaysTrueClosure always_true;
-  WeakProcessor::weak_oops_do(&always_true, oops);
-
-  if (ShenandoahStringDedup::is_enabled()) {
-    ShenandoahStringDedup::oops_do_slow(oops);
-  }
-
-  // Do thread roots the last. This allows verification code to find
-  // any broken objects from those special roots first, not the accidental
-  // dangling reference from the thread root.
-  Threads::possibly_parallel_oops_do(false, oops, &blobs);
-}
-
 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
                                                    CLDClosure* clds,
                                                    CodeBlobClosure* blobs,
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Wed May 15 14:30:22 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Wed May 15 08:58:23 2019 -0400
@@ -107,9 +107,6 @@
                         ThreadClosure* thread_cl,
                         uint worker_id);
 
-  // For slow debug/verification code
-  void process_all_roots_slow(OopClosure* oops);
-
   // Number of worker threads used by the root processor.
   uint n_workers() const;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp	Wed May 15 08:58:23 2019 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+#include "precompiled.hpp"
+
+
+#include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "code/codeCache.hpp"
+#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
+#include "gc/shenandoah/shenandoahRootVerifier.hpp"
+#include "gc/shenandoah/shenandoahStringDedup.hpp"
+#include "gc/shared/weakProcessor.inline.hpp"
+#include "memory/universe.hpp"
+#include "runtime/thread.hpp"
+#include "services/management.hpp"
+#include "utilities/debug.hpp"
+
+// Check for overflow of number of root types.
+STATIC_ASSERT((static_cast<uint>(ShenandoahRootVerifier::AllRoots) + 1) > static_cast<uint>(ShenandoahRootVerifier::AllRoots));
+
+ShenandoahRootVerifier::ShenandoahRootVerifier() : _types(AllRoots) {
+}
+
+void ShenandoahRootVerifier::excludes(RootTypes types) {
+  _types = static_cast<ShenandoahRootVerifier::RootTypes>(static_cast<uint>(_types) & (~static_cast<uint>(types)));
+}
+
+bool ShenandoahRootVerifier::verify(RootTypes type) const {
+  return (_types & type) != 0;
+}
+
+void ShenandoahRootVerifier::oops_do(OopClosure* oops) {
+  CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
+  if (verify(CodeRoots)) {
+    CodeCache::blobs_do(&blobs);
+  }
+
+  if (verify(CLDGRoots)) {
+    CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
+    ClassLoaderDataGraph::cld_do(&clds);
+  }
+
+  if (verify(SerialRoots)) {
+    Universe::oops_do(oops);
+    Management::oops_do(oops);
+    JvmtiExport::oops_do(oops);
+    JNIHandles::oops_do(oops);
+    ObjectSynchronizer::oops_do(oops);
+    SystemDictionary::oops_do(oops);
+  }
+
+  if (verify(WeakRoots)) {
+    AlwaysTrueClosure always_true;
+    WeakProcessor::weak_oops_do(&always_true, oops);
+  }
+
+  if (ShenandoahStringDedup::is_enabled() && verify(StringDedupRoots)) {
+    ShenandoahStringDedup::oops_do_slow(oops);
+  }
+
+  if (verify(ThreadRoots)) {
+    // Do thread roots the last. This allows verification code to find
+    // any broken objects from those special roots first, not the accidental
+    // dangling reference from the thread root.
+    Threads::possibly_parallel_oops_do(false, oops, &blobs);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp	Wed May 15 08:58:23 2019 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTVERIFIER_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHROOTVERIFIER_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/iterator.hpp"
+
+class ShenandoahRootVerifier : public StackObj {
+public:
+  enum RootTypes {
+    SerialRoots         = 1 << 0,
+    ThreadRoots         = 1 << 1,
+    CodeRoots           = 1 << 2,
+    CLDGRoots           = 1 << 3,
+    WeakRoots           = 1 << 4,
+    StringDedupRoots    = 1 << 5,
+    AllRoots            = (SerialRoots | ThreadRoots | CodeRoots | CLDGRoots | WeakRoots | StringDedupRoots)
+  };
+
+private:
+  RootTypes _types;
+
+public:
+  ShenandoahRootVerifier();
+
+  void excludes(RootTypes types);
+  void oops_do(OopClosure* cl);
+
+private:
+  bool verify(RootTypes type) const;
+};
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTVERIFIER_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Wed May 15 14:30:22 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp	Wed May 15 08:58:23 2019 -0400
@@ -419,7 +419,7 @@
 class ShenandoahVerifierReachableTask : public AbstractGangTask {
 private:
   const char* _label;
-  ShenandoahRootProcessor* _rp;
+  ShenandoahRootVerifier* _verifier;
   ShenandoahVerifier::VerifyOptions _options;
   ShenandoahHeap* _heap;
   ShenandoahLivenessData* _ld;
@@ -429,12 +429,12 @@
 public:
   ShenandoahVerifierReachableTask(MarkBitMap* bitmap,
                                   ShenandoahLivenessData* ld,
-                                  ShenandoahRootProcessor* rp,
+                                  ShenandoahRootVerifier* verifier,
                                   const char* label,
                                   ShenandoahVerifier::VerifyOptions options) :
     AbstractGangTask("Shenandoah Parallel Verifier Reachable Task"),
     _label(label),
-    _rp(rp),
+    _verifier(verifier),
     _options(options),
     _heap(ShenandoahHeap::heap()),
     _ld(ld),
@@ -458,7 +458,7 @@
         ShenandoahVerifyOopClosure cl(&stack, _bitmap, _ld,
                                       ShenandoahMessageBuffer("%s, Roots", _label),
                                       _options);
-        _rp->process_all_roots_slow(&cl);
+        _verifier->oops_do(&cl);
     }
 
     size_t processed = 0;
@@ -692,10 +692,9 @@
   // This verifies what application can see, since it only cares about reachable objects.
   size_t count_reachable = 0;
   if (ShenandoahVerifyLevel >= 2) {
-    ShenandoahRootProcessor rp(_heap, _heap->workers()->active_workers(),
-                               ShenandoahPhaseTimings::_num_phases); // no need for stats
+    ShenandoahRootVerifier verifier;
 
-    ShenandoahVerifierReachableTask task(_verification_bit_map, ld, &rp, label, options);
+    ShenandoahVerifierReachableTask task(_verification_bit_map, ld, &verifier, label, options);
     _heap->workers()->run_task(&task);
     count_reachable = task.processed();
   }
@@ -943,7 +942,15 @@
 
 void ShenandoahVerifier::verify_roots_no_forwarded() {
   guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens");
-  ShenandoahRootProcessor rp(_heap, 1, ShenandoahPhaseTimings::_num_phases); // no need for stats
+  ShenandoahRootVerifier verifier;
   ShenandoahVerifyNoForwared cl;
-  rp.process_all_roots_slow(&cl);
+  verifier.oops_do(&cl);
 }
+
+void ShenandoahVerifier::verify_roots_no_forwarded_except(ShenandoahRootVerifier::RootTypes types) {
+  guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens");
+  ShenandoahRootVerifier verifier;
+  verifier.excludes(types);
+  ShenandoahVerifyNoForwared cl;
+  verifier.oops_do(&cl);
+}
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp	Wed May 15 14:30:22 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp	Wed May 15 08:58:23 2019 -0400
@@ -25,6 +25,7 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHVERIFIER_HPP
 
 #include "gc/shared/markBitMap.hpp"
+#include "gc/shenandoah/shenandoahRootVerifier.hpp"
 #include "memory/allocation.hpp"
 #include "oops/oopsHierarchy.hpp"
 #include "utilities/stack.hpp"
@@ -189,6 +190,7 @@
 
   // Roots should only contain to-space oops
   void verify_roots_no_forwarded();
+  void verify_roots_no_forwarded_except(ShenandoahRootVerifier::RootTypes types);
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHVERIFIER_HPP