8212921: ZGC: Move verification to after resurrection unblocked
Reviewed-by: eosterlund
--- a/src/hotspot/share/gc/z/zAddress.hpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zAddress.hpp Fri Nov 02 07:46:00 2018 +0100
@@ -37,6 +37,7 @@
static bool is_weak_good_or_null(uintptr_t value);
static bool is_marked(uintptr_t value);
static bool is_finalizable(uintptr_t value);
+ static bool is_finalizable_good(uintptr_t value);
static bool is_remapped(uintptr_t value);
static uintptr_t address(uintptr_t value);
--- a/src/hotspot/share/gc/z/zAddress.inline.hpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zAddress.inline.hpp Fri Nov 02 07:46:00 2018 +0100
@@ -74,6 +74,10 @@
return value & ZAddressMetadataFinalizable;
}
+inline bool ZAddress::is_finalizable_good(uintptr_t value) {
+ return is_finalizable(value) && is_good(value ^ ZAddressMetadataFinalizable);
+}
+
inline bool ZAddress::is_remapped(uintptr_t value) {
return value & ZAddressMetadataRemapped;
}
--- a/src/hotspot/share/gc/z/zDriver.cpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zDriver.cpp Fri Nov 02 07:46:00 2018 +0100
@@ -33,6 +33,7 @@
#include "gc/z/zServiceability.hpp"
#include "gc/z/zStat.hpp"
#include "logging/log.hpp"
+#include "memory/universe.hpp"
#include "runtime/vm_operations.hpp"
#include "runtime/vmThread.hpp"
@@ -44,6 +45,7 @@
static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References");
static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
+static const ZStatPhasePause ZPhasePauseVerify("Pause Verify");
static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
static const ZStatPhasePause ZPhasePauseRelocateStart("Pause Relocate Start");
@@ -210,6 +212,19 @@
}
};
+class ZVerifyClosure : public ZOperationClosure {
+public:
+ virtual const char* name() const {
+ return "ZVerify";
+ }
+
+ virtual bool do_operation() {
+ ZStatTimer timer(ZPhasePauseVerify);
+ Universe::verify();
+ return true;
+ }
+};
+
class ZRelocateStartClosure : public ZOperationClosure {
public:
virtual const char* name() const {
@@ -367,25 +382,31 @@
ZHeap::heap()->destroy_detached_pages();
}
- // Phase 7: Concurrent Select Relocation Set
+ // Phase 7: Pause Verify
+ if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+ ZVerifyClosure cl;
+ vm_operation(&cl);
+ }
+
+ // Phase 8: Concurrent Select Relocation Set
{
ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
ZHeap::heap()->select_relocation_set();
}
- // Phase 8: Concurrent Prepare Relocation Set
+ // Phase 9: Concurrent Prepare Relocation Set
{
ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
ZHeap::heap()->prepare_relocation_set();
}
- // Phase 9: Pause Relocate Start
+ // Phase 10: Pause Relocate Start
{
ZRelocateStartClosure cl;
vm_operation(&cl);
}
- // Phase 10: Concurrent Relocate
+ // Phase 11: Concurrent Relocate
{
ZStatTimer timer(ZPhaseConcurrentRelocated);
ZHeap::heap()->relocate();
--- a/src/hotspot/share/gc/z/zHeap.cpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zHeap.cpp Fri Nov 02 07:46:00 2018 +0100
@@ -366,11 +366,6 @@
// Process weak roots
_weak_roots_processor.process_weak_roots();
- // Verification
- if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
- Universe::verify();
- }
-
return true;
}
@@ -570,7 +565,7 @@
_weak_roots() {}
virtual void work() {
- ZVerifyRootOopClosure cl;
+ ZVerifyOopClosure cl;
_strong_roots.oops_do(&cl);
_weak_roots.oops_do(&cl);
}
--- a/src/hotspot/share/gc/z/zOop.hpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zOop.hpp Fri Nov 02 07:46:00 2018 +0100
@@ -33,7 +33,7 @@
static uintptr_t to_address(oop o);
static bool is_good(oop o);
- static bool is_good_or_null(oop o);
+ static bool is_finalizable_good(oop o);
static oop good(oop);
};
--- a/src/hotspot/share/gc/z/zOop.inline.hpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zOop.inline.hpp Fri Nov 02 07:46:00 2018 +0100
@@ -40,8 +40,8 @@
return ZAddress::is_good(to_address(o));
}
-inline bool ZOop::is_good_or_null(oop o) {
- return ZAddress::is_good_or_null(to_address(o));
+inline bool ZOop::is_finalizable_good(oop o) {
+ return ZAddress::is_finalizable_good(to_address(o));
}
inline oop ZOop::good(oop o) {
--- a/src/hotspot/share/gc/z/zOopClosures.cpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zOopClosures.cpp Fri Nov 02 07:46:00 2018 +0100
@@ -28,54 +28,31 @@
#include "memory/iterator.inline.hpp"
#include "oops/access.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/safepoint.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
-static void z_verify_loaded_object(const oop* p, const oop obj) {
- guarantee(ZOop::is_good_or_null(obj),
- "Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT,
- p2i(obj), p2i(p), p2i(ZOop::good(obj)));
- guarantee(oopDesc::is_oop_or_null(obj),
- "Bad object " PTR_FORMAT " found at " PTR_FORMAT,
- p2i(obj), p2i(p));
-}
+void ZVerifyOopClosure::do_oop(oop* p) {
+ guarantee(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
+ guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
+ guarantee(!ZResurrection::is_blocked(), "Invalid phase");
-OopIterateClosure::ReferenceIterationMode ZVerifyHeapOopClosure::reference_iteration_mode() {
- // Don't visit the j.l.Reference.referents for this verification closure,
- // since they are cleaned concurrently after ZHeap::mark_end(), and can
- // therefore not be verified at this point.
- return DO_FIELDS_EXCEPT_REFERENT;
+ const oop o = RawAccess<>::oop_load(p);
+ if (o != NULL) {
+ guarantee(ZOop::is_good(o) || ZOop::is_finalizable_good(o),
+ "Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT,
+ p2i(o), p2i(p), p2i(ZOop::good(o)));
+ guarantee(oopDesc::is_oop(ZOop::good(o)),
+ "Bad object " PTR_FORMAT " found at " PTR_FORMAT,
+ p2i(o), p2i(p));
+ }
}
-void ZVerifyHeapOopClosure::do_oop(oop* p) {
- guarantee(ZHeap::heap()->is_in((uintptr_t)p), "oop* " PTR_FORMAT " not in heap", p2i(p));
-
- const oop obj = RawAccess<>::oop_load(p);
- z_verify_loaded_object(p, obj);
-}
-
-void ZVerifyHeapOopClosure::do_oop(narrowOop* p) {
- ShouldNotReachHere();
-}
-
-ZVerifyRootOopClosure::ZVerifyRootOopClosure() {
- // This closure should only be used from ZHeap::mark_end(),
- // when all roots should have been fixed by the fixup_partial_loads().
- guarantee(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
-}
-
-void ZVerifyRootOopClosure::do_oop(oop* p) {
- guarantee(!ZHeap::heap()->is_in((uintptr_t)p), "oop* " PTR_FORMAT " in heap", p2i(p));
-
- const oop obj = RawAccess<>::oop_load(p);
- z_verify_loaded_object(p, obj);
-}
-
-void ZVerifyRootOopClosure::do_oop(narrowOop* p) {
+void ZVerifyOopClosure::do_oop(narrowOop* p) {
ShouldNotReachHere();
}
void ZVerifyObjectClosure::do_object(oop o) {
- ZVerifyHeapOopClosure cl;
+ ZVerifyOopClosure cl;
o->oop_iterate(&cl);
}
--- a/src/hotspot/share/gc/z/zOopClosures.hpp Fri Nov 02 00:26:25 2018 -0700
+++ b/src/hotspot/share/gc/z/zOopClosures.hpp Fri Nov 02 07:46:00 2018 +0100
@@ -71,29 +71,23 @@
virtual void do_oop(narrowOop* p);
};
-class ZVerifyHeapOopClosure : public BasicOopIterateClosure {
+class ZVerifyOopClosure : public ZRootsIteratorClosure, public BasicOopIterateClosure {
public:
- virtual ReferenceIterationMode reference_iteration_mode();
-
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
+ virtual ReferenceIterationMode reference_iteration_mode() {
+ return DO_FIELDS;
+ }
+
#ifdef ASSERT
- // Verification handled by the closure itself.
+ // Verification handled by the closure itself
virtual bool should_verify_oops() {
return false;
}
#endif
};
-class ZVerifyRootOopClosure : public ZRootsIteratorClosure {
-public:
- ZVerifyRootOopClosure();
-
- virtual void do_oop(oop* p);
- virtual void do_oop(narrowOop* p);
-};
-
class ZVerifyObjectClosure : public ObjectClosure {
public:
virtual void do_object(oop o);