# HG changeset patch # User zgu # Date 1557925103 14400 # Node ID b99e97bc504076c6dedcf9f512d7a74fea22d82d # Parent 80991d58b9479275999157b24ddb88cbb07d43a8 8223215: Shenandoah: Support verifying subset of roots Reviewed-by: shade, rkennke diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- 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); diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp --- 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, diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp --- 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; }; diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp --- /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(ShenandoahRootVerifier::AllRoots) + 1) > static_cast(ShenandoahRootVerifier::AllRoots)); + +ShenandoahRootVerifier::ShenandoahRootVerifier() : _types(AllRoots) { +} + +void ShenandoahRootVerifier::excludes(RootTypes types) { + _types = static_cast(static_cast(_types) & (~static_cast(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); + } +} diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp --- /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 diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp --- 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); +} diff -r 80991d58b947 -r b99e97bc5040 src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp --- 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